The Accomodation of Students HDU - 2444
考察:二分图匹配+二分图判定
蒟蒻落泪,一开始不知道怎么分组,想了很久才发现在判定的时候就能分组.
看了一些大佬的题解,建立有向图,每个点跑一遍匹配,也能AC.但是这样感觉有点不太对,样例这样跑就会一个点连了两条边.可能我没get到大佬思路
我是采用vector存储,但没必要,用color数组的颜色判定即可
修改后的代码:
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int N = 410; 6 bool st[N>>1]; 7 int n,m,h[N],idx,match[N>>1],color[N>>1]; 8 struct Road{ 9 int u,v,ne; 10 }road[N*N/2]; 11 void inits() 12 { 13 idx = 0; 14 memset(color,0,sizeof color); 15 memset(h,-1,sizeof h); memset(match,-1,sizeof match); 16 } 17 void add(int a,int b) 18 { 19 road[idx].u = a,road[idx].v=b,road[idx].ne = h[a],h[a] = idx++; 20 } 21 bool findw(int x) 22 { 23 for(int i=h[x];i!=-1;i=road[i].ne) 24 { 25 int j = road[i].v; 26 if(st[j]) continue; 27 st[j] = 1; 28 if(match[j]==-1||findw(match[j])) 29 { 30 match[j] = x; 31 return true; 32 } 33 } 34 return false; 35 } 36 bool dfs(int x,int c) 37 { 38 color[x] = c; 39 for(int i=h[x];i!=-1;i=road[i].ne) 40 { 41 int j = road[i].v; 42 if(!color[j]) 43 { 44 color[j] = 3-c; 45 if(!dfs(j,3-c)) return false; 46 }else if(color[j]==c) return false; 47 } 48 return true; 49 } 50 int main() 51 { 52 while(scanf("%d%d",&n,&m)!=EOF) 53 { 54 bool flag = true; int res = 0; 55 inits(); 56 while(m--) 57 { 58 int x,y; scanf("%d%d",&x,&y); 59 add(x,y); add(y,x); 60 } 61 for(int i=1;i<=n;i++) 62 { 63 if(!color[i]) 64 { 65 if(!dfs(i,1)) 66 { 67 flag = false; 68 break; 69 } 70 } 71 } 72 if(!flag) { puts("No"); continue ; } 73 for(int i=1;i<=n;i++) 74 { 75 if(color[i]==2) continue; 76 memset(st,0,sizeof st); 77 if(findw(i)) res++; 78 } 79 printf("%d\n",res); 80 } 81 return 0; 82 }