uva 3523 Knights of the Round Table
题意:给你n,m n为有多少人,m为有多少组关系,每组关系代表两人相互憎恨,问有多少个骑士不能参加任何一个会议。
白书算法指南
对于每个双联通分量,若不是二分图,就把里面的节点标记
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <cstring> 10 #include <math.h> 11 #include <stdlib.h> 12 #include <time.h> 13 #include <stack> 14 using namespace std; 15 const int maxn=1010; 16 int pre[maxn],iscut[maxn],bccno[maxn],dfs_clock,bcc_cnt; 17 int A[maxn][maxn]; 18 vector<int> G[maxn],bcc[maxn]; 19 struct Edge { 20 int u,v; 21 }; 22 stack<Edge>S; 23 24 int dfs(int u,int fa) { 25 int lowu=pre[u]=++dfs_clock; 26 int child=0; 27 for(int i=0; i<G[u].size(); i++) { 28 int v=G[u][i]; 29 Edge e=(Edge) { 30 u,v 31 }; 32 if(!pre[v]) { 33 S.push(e); 34 child++; 35 int lowv=dfs(v,u); 36 lowu=min(lowu,lowv); 37 if(lowv>=pre[u]) { 38 iscut[u]=true; 39 bcc_cnt++; 40 bcc[bcc_cnt].clear(); 41 for(;;) { 42 Edge x=S.top(); 43 S.pop(); 44 if(bccno[x.u]!=bcc_cnt) { 45 bcc[bcc_cnt].push_back(x.u); 46 bccno[x.u]=bcc_cnt; 47 } 48 if(bccno[x.v]!=bcc_cnt) { 49 bcc[bcc_cnt].push_back(x.v); 50 bccno[x.v]=bcc_cnt; 51 } 52 if(x.u==u&&x.v==v) 53 break; 54 } 55 } 56 } else if(pre[v]<pre[u]&&v!=fa) { 57 S.push(e); 58 lowu=min(lowu,pre[v]); 59 } 60 } 61 if(fa<0&&child==1) 62 iscut[u]=0; 63 return lowu; 64 } 65 66 void find_bcc(int n) { 67 memset(pre,0,sizeof(pre)); 68 memset(iscut,0,sizeof(iscut)); 69 memset(bccno,0,sizeof(bccno)); 70 dfs_clock=bcc_cnt=0; 71 for(int i=0; i<n; i++) { 72 if(!pre[i]) 73 dfs(i,-1); 74 } 75 } 76 77 int odd[maxn],color[maxn]; 78 bool bipartite(int u,int b) { 79 for(int i=0; i<G[u].size(); i++) { 80 int v=G[u][i]; 81 if(bccno[v]!=b) 82 continue; 83 if(color[v]==color[u]) 84 return false; 85 if(!color[v]) { 86 color[v]=3-color[u]; 87 if(!bipartite(v,b)) 88 return false; 89 } 90 } 91 return true; 92 } 93 94 int main() { 95 int kase =0,m,n; 96 while(scanf("%d%d",&n,&m)==2&&n) { 97 for(int i=0; i<n; i++) { 98 G[i].clear(); 99 } 100 memset(A,0,sizeof(A)); 101 for(int i=0; i<m; i++) { 102 int u,v; 103 scanf("%d%d",&u,&v); 104 u--; 105 v--; 106 A[u][v]=A[v][u]=1; 107 } 108 for(int u=0; u<n; u++) { 109 for(int v=u+1; v<n; v++) { 110 if(!A[u][v]) { 111 G[u].push_back(v); 112 G[v].push_back(u); 113 } 114 } 115 } 116 find_bcc(n); 117 memset(odd,0,sizeof(odd)); 118 for(int i=1; i<=bcc_cnt; i++) { 119 memset(color,0,sizeof(color)); 120 for(int j=0; j<bcc[i].size(); j++) { 121 bccno[bcc[i][j]]=i; 122 } 123 int u=bcc[i][0]; 124 color[u]=1; 125 if(!bipartite(u,i)) { 126 for(int j=0; j<bcc[i].size(); j++) { 127 odd[bcc[i][j]]=1; 128 } 129 } 130 } 131 int ans=n; 132 for(int i=0; i<n; i++) { 133 if(odd[i]) 134 ans--; 135 } 136 printf("%d\n",ans); 137 } 138 }