现在的位置: 首页 > 算法 > 正文

zoj1462 二分图染色+DP

2019年08月20日 算法 ⁄ 共 1548字 ⁄ 字号 评论关闭

不认识的人间连边,对于每个连通分量dfs染色 再01背包DP就ok

#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
vector<int>s[2][150];
int mp[150][150],p[150][150],vi[150],dp[150][150];
int path[150],c[150];
int t,n,cnt;
struct node
{
	int x;
	int va;
};
int dfs(int i,int va)
{
	vi[i]=1;
	c[i]=va;
	s[va][cnt].push_back(i);
	for(int j=1;j<=n;j++)
		if(i!=j&&p[i][j])
		{
			if(vi[j])
			{
				if((c[i]%2)==(c[j]%2))
					return 1;
			}
			else
			if(dfs(j,va^1))
				return 1;
		}
	return 0;
}
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		cnt=0;
		for(int i=0;i<2;i++)
			for(int j=0;j<110;j++)
				s[i][j].clear();
		memset(mp,0,sizeof(mp));
		memset(p,0,sizeof(p));
		memset(vi,0,sizeof(vi));
		memset(path,0,sizeof(path));
		for(int i=1;i<=n;i++)
		{
			int a;
			while(scanf("%d",&a)==1&&a)
				mp[i][a]=1;
		}
		for(int i=1;i<=n;i++)
			for(int j=i+1;j<=n;j++)
			{
				if(mp[i][j]==0||mp[j][i]==0)
					p[i][j]=p[j][i]=1;
			}
		int ff=0;
		for(int i=1;i<=n;i++)
		{
			if(vi[i])
				continue;
			cnt++;
			if(dfs(i,1))
			{
				ff=1;
				break;
			}
		}
		if(ff)
		{
			printf("No solution\n");
			if(t)
				puts("");
			continue;
		}
		memset(dp,0,sizeof(dp));
		dp[0][0]=1;
		for(int i=1;i<=cnt;i++)
		{
			for(int j=n/2;j>=0;j--)
			{
				if(dp[i-1][j])
				{
					dp[i][j+s[0][i].size()]=1;
					dp[i][j+s[1][i].size()]=2;
				}
			}
		}
		int sum;
		for(sum=n/2;sum>=0;sum--)
		{
			if(dp[cnt][sum])
				break;
		}
		int index=0;
		for(int i=cnt;i>=1;i--)
		{
			if(dp[i][sum]==1)
			{
				sum-=s[0][i].size();
				for(int j=0;j<s[0][i].size();j++)
					path[++index]=s[0][i][j];
			}
			else
			{
				sum-=s[1][i].size();
				for(int j=0;j<s[1][i].size();j++)
					path[++index]=s[1][i][j];
			}
		}
		memset(vi,0,sizeof(vi));
		printf("%d",index);
		for(int i=1;i<=index;i++)
		{
			printf(" %d",path[i]);
			vi[path[i]]=1;
		}
		puts("");
		printf("%d",n-index);
		for(int i=1;i<=n;i++)
		{
			if(!vi[i])
				printf(" %d",i);
		}
		puts("");
		if(t)puts("");
	}
	return 0;
}
【上篇】
【下篇】

抱歉!评论已关闭.