1059: [ZJOI2007] Matrix Game

1059: [ZJOI2007] Matrix Game

 

Link

Ideas:

  The condition that can be filled on the diagonal is that each row, each column, must have a number. So think of a column as a row of dots and a row as a row of dots. For bipartite graph matching, the number of matching is required to be n, that is, all matching is successful.

 

Code:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cctype>
 5  
 6 using namespace std;
 7 
 8 const int N = 510; // 两倍空间! 
 9 const int INF = 1e9;
10 struct Edge{
11     int to,nxt,c;
12     Edge() {}
13     Edge(int x,int y,int z) {to = x;c = y;nxt = z;}
14 }e[100100];
15 int head[N],dis[N],cur[N],q[100100];
16 int S,T,tot,L,R;
17 
18 inline int read() {
19     int x = 0,f = 1;char ch = getchar();
20     for (; !isdigit(ch); ch=getchar()) if(ch=='-') f = -1;
21     for (; isdigit(ch); ch=getchar()) x = x*10+ch-'0';
22     return x * f;
23 }
24 
25 void init() {
26     tot = 1;
27     memset(head,0,sizeof(head));
28 }
29 void add_edge(int u,int v,int w) {
30     e[++tot] = Edge(v,w,head[u]);head[u] = tot;
31     e[++tot] = Edge(u,0,head[v]);head[v] = tot;
32 }
33 bool bfs() {
34     for (int i=1; i<=T; ++i) cur[i] = head[i],dis[i] = -1;
35     L = 1;R = 0;
36     q[++R] = S;
37     dis[S] = 1;
38     while (L <= R) {
39         int u = q[L++];
40         for (int i=head[u]; i; i=e[i].nxt) {
41             int v = e[i].to;
42             if (dis[v] == -1 && e[i].c > 0) {
43                 dis[v] = dis[u] + 1;
44                 q[++R] = v;
45                 if (v==T) return true;
46             }
47         }
48     }
49     return false;
50 }
51 int dfs(int u,int flow) {
52     if (u == T) return flow;
53     int used = 0,tmp;
54     for (int &i=cur[u]; i; i=e[i].nxt) {
55         int v = e[i].to;
56         if (dis[v] == dis[u] + 1 && e[i].c > 0) {
57             tmp = dfs(v,min(e[i].c,flow-used));
58             if (tmp) {
59                 e[i].c -= tmp;e[i^1].c += tmp;
60                 used += tmp;
61                 if (used == flow) break;
62             }
63         }
64     }
65     if (used != flow) dis[u] = -1;
66     return used;
67 }
68 int dinic() {
69     int ans = 0;
70     while (bfs()) ans += dfs(S,INF);
71     return ans;
72 }
73 int main() {
74     int Case = read(); // 不要设成T 
75     while (Case--) {
76         init();
77         int n = read();
78         S = n+n+1,T = n+n+2;
79         for (int i=1; i<=n; ++i) 
80             for (int j=1; j<=n; ++j) {
81                 int a = read();
82                 if (a) add_edge(i,j+n,1);
83             }
84         for (int i=1; i<=n; ++i) 
85             add_edge(S,i,1),add_edge(i+n,T,1);
86         int ans = dinic();
87         if (ans==n) puts("Yes");
88         else puts("No");
89     }
90     return 0;
91 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325266167&siteId=291194637