【01染色法判断二分匹配+匈牙利算法求最大匹配】HDU The Accomodation of Students
http://acm.hdu.edu.cn/showproblem.php?pid=2444
【DFS染色】
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 8 using namespace std; 9 const int maxn=2e2+3; 10 const int maxm=maxn*maxn; 11 struct edge 12 { 13 int to; 14 int nxt; 15 }e[maxm]; 16 int tot; 17 int head[maxn]; 18 int col[maxn]; 19 bool vis[maxn]; 20 int link[maxn]; 21 void init() 22 { 23 tot=0; 24 memset(head,-1,sizeof(head)); 25 memset(col,0,sizeof(col)); 26 memset(link,-1,sizeof(link)); 27 } 28 29 void add(int u,int v) 30 { 31 e[tot].to=v; 32 e[tot].nxt=head[u]; 33 head[u]=tot++; 34 } 35 bool Color(int u) 36 { 37 for(int i=head[u];i!=-1;i=e[i].nxt) 38 { 39 int v=e[i].to; 40 if(!col[v]) 41 { 42 col[v]=!col[u]; 43 if(!Color(v)) 44 { 45 return false; 46 } 47 } 48 else if(col[v]==col[u]) 49 { 50 return false; 51 } 52 } 53 return true; 54 } 55 bool find(int u) 56 { 57 for(int i=head[u];i!=-1;i=e[i].nxt) 58 { 59 int v=e[i].to; 60 if(!vis[v]) 61 { 62 vis[v]=true; 63 if(link[v]==-1||find(link[v])) 64 { 65 link[v]=u; 66 return true; 67 } 68 } 69 } 70 return false; 71 } 72 int n,m; 73 int main() 74 { 75 while(~scanf("%d%d",&n,&m)) 76 { 77 init(); 78 while(m--) 79 { 80 int u,v; 81 scanf("%d%d",&u,&v); 82 add(u,v); 83 add(v,u); 84 } 85 col[1]=1; 86 if(!Color(1)) 87 { 88 puts("No"); 89 continue; 90 } 91 int ans=0; 92 for(int i=1;i<=n;i++) 93 { 94 memset(vis,false,sizeof(vis)); 95 if(find(i)) 96 { 97 ans++; 98 } 99 } 100 printf("%d\n",ans/2); 101 } 102 return 0; 103 }
【BFS染色】
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 using namespace std; 9 const int maxn=2e2+3; 10 const int maxm=maxn*maxn; 11 struct edge 12 { 13 int to; 14 int nxt; 15 }e[maxm]; 16 int tot; 17 int head[maxn]; 18 int col[maxn]; 19 bool vis[maxn]; 20 int link[maxn]; 21 void init() 22 { 23 tot=0; 24 memset(head,-1,sizeof(head)); 25 memset(col,0,sizeof(col)); 26 memset(link,-1,sizeof(link)); 27 } 28 29 void add(int u,int v) 30 { 31 e[tot].to=v; 32 e[tot].nxt=head[u]; 33 head[u]=tot++; 34 } 35 bool Color(int u) 36 { 37 queue<int> Q; 38 Q.push(u); 39 while(!Q.empty()) 40 { 41 u=Q.front(); 42 Q.pop(); 43 for(int i=head[u];i!=-1;i=e[i].nxt) 44 { 45 int v=e[i].to; 46 if(!col[v]) 47 { 48 col[v]=!col[u]; 49 Q.push(v); 50 } 51 else if(col[v]==col[u]) 52 { 53 return false; 54 } 55 } 56 } 57 return true; 58 } 59 bool find(int u) 60 { 61 for(int i=head[u];i!=-1;i=e[i].nxt) 62 { 63 int v=e[i].to; 64 if(!vis[v]) 65 { 66 vis[v]=true; 67 if(link[v]==-1||find(link[v])) 68 { 69 link[v]=u; 70 return true; 71 } 72 } 73 } 74 return false; 75 } 76 int n,m; 77 int main() 78 { 79 while(~scanf("%d%d",&n,&m)) 80 { 81 init(); 82 while(m--) 83 { 84 int u,v; 85 scanf("%d%d",&u,&v); 86 add(u,v); 87 add(v,u); 88 } 89 col[1]=1; 90 if(!Color(1)) 91 { 92 puts("No"); 93 continue; 94 } 95 int ans=0; 96 for(int i=1;i<=n;i++) 97 { 98 memset(vis,false,sizeof(vis)); 99 if(find(i)) 100 { 101 ans++; 102 } 103 } 104 printf("%d\n",ans/2); 105 } 106 return 0; 107 }
匈牙利算法: