【洛谷 P1129】 [ZJOI2007]矩陣遊戲
阿新 • • 發佈:2018-10-14
read del .org 鏈接 矩陣 ems efi lse pan
題目鏈接
看到題目肯定首先會想到搜索。
然鵝數據範圍\(n<=200\)這麽大(其實也不算太大),肯定是不行的。
如果\((i,j)\)是\(1\),從\(i\)向\(j\)連一條邊,表示第\(j\)列可以交換第\(i\)列得到,然後跑一遍匈牙利就行了(Dinic我不會啊)。
#include <cstdio> #include <cstring> #include <algorithm> #define Open(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout); #define Close fclose(stdin);fclose(stdout); using namespace std; int s; char ch; inline int read(){ s = 0; ch = getchar(); while(ch < '0' || ch > '9') ch = getchar(); while(ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar(); } return s; } const int MAXN = 1010; const int MAXM = MAXN * MAXN; int match[MAXN], vis[MAXN]; int n, T, a, Time, head[MAXN], num, ans; struct Edge{ int next, to; }e[MAXM << 1]; inline void Add(int from, int to){ e[++num].to = to; e[num].next = head[from]; head[from] = num; } int find(int u){ for(int i = head[u]; i; i = e[i].next) if(vis[e[i].to] != Time){ vis[e[i].to] = Time; if(!match[e[i].to] || find(match[e[i].to])){ match[e[i].to] = u; return 1; } } return 0; } int main(){ T = read(); while(T--){ memset(head, 0, sizeof head); memset(match, 0, sizeof match); num = 0; n = read(); ans = 0; for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) if(read()) Add(i, j); for(int i = 1; i <= n; ++i) ++Time, ans += find(i); if(ans == n) printf("Yes\n"); else printf("No\n"); } return 0; }
【洛谷 P1129】 [ZJOI2007]矩陣遊戲