HDU2444-The Accomodation of Students-判断是否为二分图+ISAP
要先判断是不是二分图。用黑白染色法。
遇到已经染过的跟当前的颜色相同时就说明不是二分图,也即出现了奇环
1 /*--------------------------------------------------------------------------------------*/ 2 3 #include <algorithm> 4 #include <iostream> 5 #include <cstring> 6 #include <ctype.h> 7 #include <cstdlib> 8 #include <cstdio> 9 #include <vector> 10 #include <string> 11 #include <queue> 12 #include <stack> 13 #include <cmath> 14 #include <set> 15 #include <map> 16 17 //debug function for a N*M array 18 #define debug_map(N,M,G) printf("\n");for(int i=0;i<(N);i++)\ 19 {for(int j=0;j<(M);j++){\ 20 printf("%d",G[i][j]);}printf("\n");} 21 //debug function for int,float,double,etc. 22 #define debug_var(X) cout<<#X"="<<X<<endl; 23 #define LL long long 24 const int INF = 0x3f3f3f3f; 25 const LL LLINF = 0x3f3f3f3f3f3f3f3f; 26 /*--------------------------------------------------------------------------------------*/ 27 using namespace std; 28 29 int N,M,T; 30 31 const int maxn = 300; 32 const int maxm = 30000; 33 struct Edge{ 34 int to,next; 35 }edge[maxm]; 36 37 int head[maxn],tot; 38 void init() 39 { 40 tot = 0; 41 memset(head,-1,sizeof head); 42 } 43 void add_edge(int u,int v) 44 { 45 edge[tot].to = v;edge[tot].next = head[u]; 46 head[u] = tot++; 47 } 48 49 int linker[maxn]; 50 bool used[maxn]; 51 int uN; 52 53 bool dfs(int u) 54 { 55 for(int i=head[u];~i;i=edge[i].next) 56 { 57 int v = edge[i].to; 58 if(!used[v]) 59 { 60 used[v] = true; 61 if(linker[v] == -1 || dfs(linker[v])) 62 { 63 linker[v] = u; 64 return true; 65 } 66 } 67 } 68 return false; 69 } 70 int hungary() 71 { 72 int res = 0; 73 memset(linker,-1,sizeof linker); 74 for(int u=1;u<=uN;u++) 75 { 76 memset(used,false,sizeof used); 77 if(dfs(u)) res++; 78 } 79 return res/2; 80 } 81 82 int col[maxn]; 83 bool isBipartite(int u) 84 { 85 queue<int> Q; 86 Q.push(u); 87 col[u] = 1; 88 while(!Q.empty()) 89 { 90 int cur = Q.front();Q.pop(); 91 for(int i = head[cur];~i;i=edge[i].next) 92 { 93 int v = edge[i].to; 94 if(col[v] == col[cur]) return false; 95 if(col[v] != -1) continue; 96 col[v] = !col[cur]; 97 Q.push(v); 98 } 99 } 100 return true; 101 } 102 103 int main() 104 { 105 while(~scanf("%d%d",&N,&M)) 106 { 107 init(); 108 uN = N; 109 for(int i=0,u,v;i<M;i++) 110 { 111 scanf("%d%d",&u,&v); 112 add_edge(u,v); 113 add_edge(v,u); 114 } 115 116 bool flag = true; 117 memset(col,-1,sizeof col); 118 for(int i=1;i<=uN;i++) if(col[i] == -1) 119 { 120 if(!isBipartite(i) ){flag = false;break;} 121 } 122 if(flag) 123 { 124 printf("%d\n",hungary()); 125 } 126 else printf("No\n"); 127 128 } 129 }