題目連結在這裡:B (codeforces.com)
1 #include "bits/stdc++.h"
2 using namespace std;
3 const int MAX=505;
4 int n,m,tot,cnt,fa[MAX];
5 int head[MAX],nxt[MAX*MAX],adj[MAX*MAX];
6 int vis[MAX],id[MAX],ff[MAX],mat[MAX],ans;
7 int q[2000005],st,ed;
8 char s[MAX];
9 inline int getfather(int x){return (fa[x]==x?x:fa[x]=getfather(fa[x]));}
10 inline int read(){
11 int an=0,x=1;char c=getchar();
12 while (c<'0' || c>'9') {if (c=='-') x=-1;c=getchar();}
13 while (c>='0' && c<='9') {an=an*10+c-'0';c=getchar();}
14 return an*x;
15 }
16 inline void addedge(int u,int v){
17 tot++;
18 adj[tot]=v;
19 nxt[tot]=head[u];
20 head[u]=tot;
21 }
22 inline int lca(int x,int y){
23 cnt++;
24 while (vis[x]!=cnt){
25 if (x){
26 x=getfather(x);
27 if (vis[x]==cnt) return x;
28 vis[x]=cnt;
29 if (mat[x]!=0)
30 x=getfather(ff[mat[x]]);
31 else x=0;
32 }
33 swap(x,y);
34 }
35 return x;
36 }
37 inline void work(int x,int y,int k){
38 int z;
39 while (getfather(x)!=k){
40 ff[x]=y;
41 z=mat[x];
42 if (id[z]==1){
43 id[z]=0;
44 q[++ed]=z;
45 }
46 if (getfather(z)==z) fa[z]=k;
47 if (getfather(x)==x) fa[x]=k;
48 y=z;x=ff[y];
49 }
50 }
51 inline bool bfs(int x){
52 int i,j,u,v;
53 int la,no,t,z;
54 for (i=1;i<=n;i++) fa[i]=i;
55 memset(id,-1,sizeof(id));
56 st=ed=0;
57 q[++ed]=x;id[x]=0;
58 while (st<ed){
59 u=q[++st];
60 for (i=head[u];i;i=nxt[i]){
61 v=adj[i];
62 if (id[v]==-1){
63 ff[v]=u,id[v]=1;
64 if (!mat[v]){
65 no=v;
66 while (no){
67 t=ff[no];
68 la=mat[t];
69 mat[t]=no;mat[no]=t;
70 no=la;
71 }
72 return true;
73 }
74 id[mat[v]]=0;
75 q[++ed]=mat[v];
76 }
77 else if (id[v]==0 && getfather(u)!=getfather(v)){
78 z=lca(u,v);
79 work(u,v,z);work(v,u,z);
80 }
81 }
82 }
83 return false;
84 }
85 int main(){
86 freopen ("b.in","r",stdin);freopen ("b.out","w",stdout);
87 int i,j,u,v,cas;
88 scanf("%d",&cas);
89 while (cas--){
90 n=read(),m=read();
91 // scanf("%d %d",&n,&m);
92 ans=tot=cnt=0;
93 memset(head,0,sizeof(head));
94 memset(ff,0,sizeof(ff));
95 memset(vis,0,sizeof(vis));
96 memset(mat,0,sizeof(mat));
97 memset(fa,0,sizeof(fa));
98 int now=n;
99 for (i=1;i<=n;i++){
100 scanf("\n%s",s+1);
101 addedge(i,i+n);
102 addedge(i+n,i);
103 for (j=1;j<=m;j++)
104 if (s[j]=='1'){
105 addedge(i,2*n+j);
106 addedge(2*n+j,i);
107 addedge(i+n,2*n+j);
108 addedge(2*n+j,i+n);
109 }
110 }
111 n=2*n+m;
112 for (i=1;i<=n;i++)
113 if (!mat[i] && bfs(i))
114 ans++;
115 printf("%d\n",ans-now);
116 }
117 return 0;
118