bzoj 1059: [ZJOI2007]矩阵游戏
尼玛这道题一开始我printf(“Yse\n”)调了我半个小时,最后还是葱娘给看出来的(英语渣给跪了Orz)
这道题我莫名其妙地只想了一会儿(要知道我前一天才会的匈牙利,还是自学的!!),当时觉得我自己叼的跟坨翔样的
同行同列的点无论经过多少次变换人仍然同行或同列,所以题目可转换为能不能找到n个互相不同行或同列的点。
然后二分图匹配,将行和列分别看成一个点集,每有一个‘1’的点就把他的行和列连一条边,看每一行能不能找到一个列与之匹配。
1 /* 2 ID:WULALA 3 PROB:bzoj1059 4 LANG:C++ 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <algorithm> 9 #include <cmath> 10 #include <iostream> 11 #include <fstream> 12 #include <ctime> 13 #define N 208 14 #define M 40008 15 #define mod 16 #define mid(l,r) ((l+r) >> 1) 17 #define INF 0x7ffffff 18 using namespace std; 19 20 int T,n,mate[N]; 21 bool vis[N],map[N][N]; 22 23 void init() 24 { 25 memset(map,false,sizeof(map)); 26 memset(mate,0,sizeof(mate)); 27 memset(vis,false,sizeof(vis)); 28 scanf("%d",&n); 29 for (int i = 1;i <= n;i++) 30 for (int j = 1;j <= n;j++) 31 { 32 int a; 33 scanf("%d",&a); 34 if (a) map[i][j] = true; 35 } 36 } 37 38 bool find(int a) 39 { 40 for (int i = 1;i <= n;i++) 41 if (!vis[i]&&map[a][i]) 42 { 43 vis[i] = true; 44 { 45 if (!mate[i]||find(mate[i])) 46 { 47 mate[i] = a; 48 return true; 49 } 50 } 51 } 52 return false; 53 } 54 55 void work() 56 { 57 init(); 58 for (int i = 1;i <= n;i++) 59 { 60 memset(vis,false,sizeof(vis)); 61 if (!find(i)) 62 { 63 printf("No\n"); 64 return; 65 } 66 } 67 printf("Yes\n"); 68 } 69 70 int main() 71 { 72 scanf("%d",&T); 73 for (int i = 1;i <= T;i++) 74 work(); 75 return 0; 76 }