這題debug的好鬱悶啊!!!先是染色有問題,然後就是各種小錯誤....
判奇圈可以用二分表徵圖准,因為奇圈肯定不是二分圖,之前還要分離各雙連通分量.......染色法判二分圖一定要先對分量裡每一個點都染一次色再枚舉任意兩個相鄰的點看是否有同色,就是因為這裡wa了n次!!!
#define N 1005vector<int> v[N];vector<int> lin[N];int dfn[N],low[N];bool instack[N],iscut[N];int num_rt;int cnt;int step;stack<int> sta;bool g[N][N];void init(int n){ for(int i=0;i<=n;i++){ instack[i] = 0; iscut[i] = 0; dfn[i] = 0; low[i] = 0; } step = 0; cnt = 0; while(!sta.empty())sta.pop();}void tarjan(int u,int fa){ low[u] = dfn[u] = ++step; sta.push(u); instack[u] = 1; int i; for(i=0;i<v[u].size();i++){ int to = v[u][i]; if(to==fa)continue; if(!dfn[to]){ tarjan(to,u); low[u] = min(low[u],low[to]); if(low[to]>=dfn[u]){ if(fa==-1)num_rt++; else iscut[u] = 1; while(1){ int tmp = sta.top(); sta.pop(); iscut[tmp] = 0; instack[tmp] = 0; lin[cnt].push_back(tmp); if(tmp==to)break; } lin[cnt].push_back(u); cnt++; } } else if(instack[to]) low[u] = min(low[u],dfn[to]); }}int col[N];bool dfs(int id,int u,int c){ int i; col[u] = c; for(i=0;i<lin[id].size();i++){ int to = lin[id][i]; if(u==to || col[to]!=-1)continue; if(g[u][to]){ dfs(id,to,c^1); } } return true;}bool ok[N];int solve(int n){ int i,j; for(i=1;i<=n;i++){ if(!dfn[i]){ num_rt = 0; tarjan(i,-1); if(num_rt>=2){ iscut[i] = 1; } } } int ans = 0; memset(ok,false,sizeof(ok)); bool tag = 0; for(i=0;i<cnt;i++){ for(j=0;j<=n;j++)col[j]=-1; int sz = lin[i].size(); dfs(i,lin[i][0],1); bool tag = 0; for(j=0;j<sz;j++){ for(int k=0;k<sz;k++){ int a = lin[i][j],b = lin[i][k]; if(a!=b && g[a][b] && col[a]==col[b]){ tag = 1; break; } } if(tag)break; } if(tag){ for(j=0;j<sz;j++){ ok[lin[i][j]] = 1; } } } for(i=1;i<=n;i++){ if(!ok[i])ans++; } return ans;}int main(){ int n,m; while(scanf("%d%d",&n,&m) &&(n+m)){ int i,j; memset(g,true,sizeof(g)); init(n); while(m--){ int x,y; scanf("%d%d",&x,&y); g[x][y] = g[y][x] = false; } for(i=0;i<=n;i++){ v[i].clear(); lin[i].clear(); } for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ if(g[i][j] && i!=j){ v[i].push_back(j); } } } printf("%d\n",solve(n)); } return 0;}