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 }
View Code

 

posted @ 2014-01-06 19:12  乌拉拉979  阅读(175)  评论(0编辑  收藏  举报