http://blog.csdn.net/lyy289065406/article/details/6756821 http://www.cnblogs.com/wuyiqi/archive/2011/10/19/2217911.html #include "stdio.h" #include "string.h" #define N 1010 int time; int n,m; bool map[N][N]; struct node { int x,y; //int weight; bool visit; //用来标记该边是否已经访问 int next; }edge[2*N*N]; int idx,head[N]; bool odd[N]; bool mark[N]; //标记点是否为当前双连通分量中的元素 int low[N],dfn[N]; int st[N*N],top; //模拟栈 int col[N]; void Read_date(); inline int MIN(int a,int b) { return a<b?a:b; } void Init(){ idx=0; memset(head,-1,sizeof(head)); } void Add(int x,int y) { edge[idx].x = x; edge[idx].y = y; edge[idx].visit = false; edge[idx].next = head[x]; head[x] = idx++; } bool find(int x) //判断当前双连通分量是否为二分图 { int i,y; for(i=head[x]; i!=-1; i=edge[i].next) { y = edge[i].y; if(mark[y]) { if(col[y]==-1) { col[y] = !col[x]; return find(y); } else if(col[y]==col[x]) return false; //不是二分图,返回false } } return true; //是二分图,返回true } void Color(int x) { int i; memset(mark,false,sizeof(mark)); while(1) { i = st[top]; top--; mark[edge[i].x] = true; mark[edge[i].y] = true; if(edge[i].x==x) break; } memset(col,-1,sizeof(col)); col[x] = 0; if(!find(x)) //双连通分量不是二分图,则这些点全部可以 { for(i=1; i<=n; ++i) { if(mark[i]) odd[i] = 1; } } } void DFS(int x) { int i,y; low[x] = dfn[x] = ++time; for(i=head[x]; i!=-1; i=edge[i].next) { y = edge[i].y; if(edge[i].visit) continue; edge[i].visit = edge[i^1].visit = 1;//走过的边不能再走了 st[++top] = i; if(!dfn[y]) { DFS(y); low[x] = MIN(low[x],low[y]); if(low[y]>=dfn[x]) //找到割顶或者为根节点 Color(x); } else low[x] = MIN(low[x],dfn[y]); } } int Solve() { int i; int num=0; time = 0; top = 0; memset(dfn,0,sizeof(dfn)); memset(odd,false,sizeof(odd)); for(i=1; i<=n; ++i) { if(!dfn[i]) //表示点i未被访问过 DFS(i); //以i为根节点找双连通分量 } for(i=1; i<=n; ++i) { if(!odd[i]) num++; } return num; } int main() { while(scanf("%d%d",&n,&m),n||m) { Read_date(); printf("%d ",Solve()); } return 0; } void Read_date() { int i,j; int x,y; memset(map,true,sizeof(map)); while(m--) { scanf("%d %d",&x,&y); map[x][y] = map[y][x] = false; } Init(); for(i=1; i<=n; ++i) { for(j=i+1; j<=n; ++j) { if(map[i][j]) { Add(i,j); Add(j,i); } } } }