hdu 5285 wyh2000 and pupil(二分图判定)

对每两个不认识的人连一条边,则此题可转化为二分图判定(用染色法。注意:二分图可有多个)。

如果有一部分图判定为不是二分图,则输出“Poor wyh”。

否则,分别累加每个二分图的最多的颜色数。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
typedef long long ll;
using namespace std;

const int inf=0x3f3f3f3f;
const int maxn=100000+10;

vector <int> g[maxn];
int color[maxn];//-1代表无颜色,0和1代表两种对立的颜色。
int n,m;

int bfs(int s){
	//printf("bfs: %d
",s );
	queue<int>q;
	q.push(s);
	color[s]=0;
	int n1=0,n0=0;//统计两种颜色的个数。

	while(!q.empty()){
		int start=q.front();
		q.pop();

		if(color[start]==0)n0++;
		else n1++;

		int len=g[start].size();
		for(int i=0;i<len;++i){
			int tmp=g[start][i];
			//printf("this is %d-%d
",start,tmp );
			if( color[ tmp ]==-1 ){
			 	q.push(tmp);
			 	color[tmp]=( color[start]+1 )%2;
			}
			else if(color[start]==color[tmp]){
				//printf("color[%d]==color[%d]
",start,tmp);
				return -1;
			}
		}
	}
	return max(n0,n1);
}

int main()
{
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%d %d",&n,&m);

		for(int i=1;i<=n;i++)g[i].clear();
		memset(color,-1,sizeof color);

		int u,v;
		for(int i=0;i<m;++i){
			scanf("%d %d",&u,&v);
			g[u].push_back(v);
			g[v].push_back(u);
		}

		int ans=0;
		for(int i=1;i<=n;++i){
			if(color[i]==-1){
				int rtn=bfs(i);
				//printf("rtn==%d
",rtn );
				if(rtn==-1){//此处少写个等号,害我Debug半天。改正后,一次AC
					ans=-1;
					break;
				}
				ans+=rtn;
			}
		}
		//printf("ans==%d
", ans);
		if(ans==-1 || n<2 ){
			printf("Poor wyh
");
		}else if(ans==n){
			printf("%d %d
",ans-1,n-ans+1 );
		}else {
			printf("%d %d
",ans,n-ans );
		}
	}
	return 0;
}

PS:这道题是我第一次用Vector表示图  :)

原文地址:https://www.cnblogs.com/bruce27/p/4799285.html