Gym
来源:互联网 发布:mysql和oracle语法区别 编辑:程序博客网 时间:2024/06/06 11:03
题目链接:https://vjudge.net/contest/181019#problem/F
题意:给定一个n*n的矩阵,从左下至右上平行于对角线的斜线共2*n-1条(包括对角线),在每条斜线上选取一个出现的值,要求这2*n-1条斜线选取的值互不相同,求是否能选取,若不能,输出NO,若能,输出YES并按1~2*n-1的顺序输出每条斜线上选取的值。
思路:从左下至右上为这些斜线编号为1~2*n-1,将编号x与斜线x上出现的数值进行连线,求出最大匹配数是否为2*n-1即可。注意数值较大,可以为每个数赋一个较小的id值放置vis数组越界。
代码如下:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<cstdlib>#include<sstream>#include<deque>#include<stack>#include<set>#include<map>using namespace std;typedef long long ll;typedef unsigned long long ull;const double eps = 1e-6;const int maxn = 1000 + 20;const int maxt = 300 + 10;const int mod = 10;const int dx[] = {1, -1, 0, 0};const int dy[] = {0, 0, -1, 1};const int Dis[] = {-1, 1, -5, 5};const int inf = 0x3f3f3f3f;const int MOD = 1000;int n, m, k;int d[maxn][maxn];int match[100000 + 10];//因match数组开小WA一次bool vis[100000 + 10];//因vis数组开太小RE一次vector<int> g[maxn];map<int, int> id;map<int, int> pos;int ans[maxn];bool dfs(int u){ int v; int len = g[u].size(); for(int i = 0; i < len; ++i){ v = g[u][i]; if(vis[v]) continue; vis[v] = true; if(match[v] == -1 || dfs(match[v])){ match[v] = u; ans[u] = v;//记录每条斜线的当前匹配值 return true; } } return false;}int main(){ scanf("%d", &n); int xx = 610; id.clear(); pos.clear(); memset(d, 0, sizeof d); for(int i = 0; i < maxn; ++i) g[i].clear(); for(int i = 1; i <= n; ++i){ for(int j = 1; j <= n; ++j){ scanf("%d",&d[i][j]); if(id.find(d[i][j]) == id.end()){//d[i][j]的值太大,根据输入顺序为其编号,防止RE id[d[i][j]] = xx; pos[xx++] = d[i][j]; } } } int t = n; int num = 1, x = 2 * n; while(t >= 1){//遍历每一条斜线,从左下至右上id编号依次为1~2*n-1,将斜线上存在的数值id值与斜线id值连线 for(int i = t, j = 1; i <= n; ++i,++j){ if(t != 1){ g[num].push_back(id[d[i][j]]); g[x - num].push_back(id[d[j][i]]); } else{ g[num].push_back(id[d[i][j]]); } } ++num; --t; } int cnt = 0; bool ok = true; memset(ans, 0, sizeof ans); memset(match, -1, sizeof match); for(int i = 1; i < x; ++i){//为每一条斜线寻找匹配值 memset(vis, false, sizeof vis); if(dfs(i)){ ++cnt; } else{//若有某条斜线无匹配值,直接退出 ok = false; break; } } if(!ok || cnt != 2 * n - 1){ printf("NO\n"); return 0; } printf("YES"); for(int i = 1; i < x; ++i){ printf(" %d", pos[ans[i]]); } printf("\n"); return 0;}/*51000000000 1000000000 1000000000 900000000 2100000001000000000 200000000 200000000 800000000 7000000001000000000 200000000 300000000 300000000 7000000001000000000 200000000 600000000 400000000 700000000700000000 700000000 700000000 00000000 700000000//1 2 6 4 3 8 941 1 1 91 2 2 81 2 4 41 2 6 551 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 2021 22 23 24 2531 1 12 2 43 1 1*/
阅读全文
0 0
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- springmvc集成shiro后,session、request姓什么?
- python2/3---sort方法与sorted函数的使用
- Android 监听软键盘弹出
- Xor Sum Gym
- Windows Practice_文件搜索器(四)_封装文件扫描器
- Gym
- Codeforces 845 C Two TVs
- java lambda表达式
- Windows Practice_闹钟(一)_简易记事本
- 门面模式
- k-近邻算法
- $n$-Way Tie Gym
- python学习(一)之初探
- 关于Arduino与STM32