poj 3648 (2-STA)

2-STA求解问题,2-SAT最重要的就是如果a与b矛盾,就加边a—>b',

因为新娘不能看到有不正当关系的两人,所以只需要在每对夫妇中选一个坐在新娘对面,

他们之间没有关系不正当的人。






#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
#define N 500
using namespace std;
int n,m,low[N],dfs[N],ins[N],belong[N],link[N];
int ans,idx,first[N],first1[N],num,num1,cf[N],color[N],indeg[N];
struct eage
{
	int ed,next;
}E[N*N],E1[N*N];
void addeage(int x,int y)
{
	E[num].ed=y;
	E[num].next=first[x];
	first[x]=num++;
}
void addeage1(int x,int y)
{
	E1[num1].ed=y;
	E1[num1].next=first1[x];
	first1[x]=num1++;
}
void insit()
{
	memset(color,0,sizeof(color));
	memset(dfs,-1,sizeof(dfs));
	memset(ins,0,sizeof(ins));
	memset(first,-1,sizeof(first));	
	memset(indeg,0,sizeof(indeg));
	memset(first1,-1,sizeof(first1));
	memset(link,0,sizeof(link));
	num=ans=idx=0;num1=0;
}
stack<int>Q;
void Tarjan(int x)
{
	int p,v;
	low[x]=dfs[x]=idx++;
	ins[x]=1;
	Q.push(x);
	for(p=first[x];p!=-1;p=E[p].next)
	{
		v=E[p].ed;
		if(dfs[v]==-1)
		{
			Tarjan(v);
			low[x]=low[x]>low[v]?low[v]:low[x];
		}
		else if(ins[v]==1)
		{
			low[x]=low[x]>dfs[v]?dfs[v]:low[x];
		}
	}
	if(dfs[x]==low[x])
	{
		do
		{
			v=Q.top();
			Q.pop();
			ins[v]=0;
			belong[v]=ans;
		}while(v!=x);
		ans++;
	}
}
void topsort()
{
	queue<int>QQ;
	int i,v,p,q;
	for(i=0;i<ans;i++)
		if(indeg[i]==0)
			QQ.push(i);
		while(!QQ.empty())
		{
			v=QQ.front();
			QQ.pop();
			if(color[v]==0)
			{
				color[v]=1;
				color[cf[v]]=-1;
			}
			for(p=first1[v];p!=-1;p=E1[p].next)
			{
				q=E1[p].ed;
				indeg[q]--;
				if(indeg[q]==0)
					QQ.push(q);           
			}
		} 
}
void solvd()
{
	int i,v;
    for(i=0;i<2*n;i++)
	{
		for(int p=first[i];p!=-1;p=E[p].next)
		{
			v=E[p].ed;
			if(belong[i]!=belong[v])
			{
				addeage1(belong[v],belong[i]);
				indeg[belong[i]]++;
			}
		}
	}
	topsort();	
	for(i=0;i<n;i++)
	{
		if(color[belong[i]]==1)
			link[i]=1;
	}
	for(i=1;i<n;i++)
	{
		if(link[i]==1)
			printf("%dh ",i);
		else printf("%dw ",i);
	}
	printf("\n");
}
int main()
{
	int i,x,x1,y,y1;
	char ch1,ch2;
	while(scanf("%d%d",&n,&m),n||m)
	{
		insit();
		for(i=0;i<m;i++)
		{
            scanf("%d%c %d%c",&x,&ch1,&y,&ch2);
			if(ch1=='h')
				x1=x,x+=n;
			else x1=x+n;
			if(ch2=='h')
				y1=y,y+=n;
			else y1=y+n;
			addeage(x,y1);
			addeage(y,x1);
		}
		addeage(0,n);
		
		for(i=0;i<n*2;i++)
		{
			if(dfs[i]==-1)
				Tarjan(i);
		}
		for(i=0;i<n;i++)
		{
			if(belong[i]==belong[i+n])
				break;
			cf[belong[i]]=belong[i+n];
			cf[belong[i+n]]=belong[i];
		}
		if(i==n)
			solvd();
		else printf("bad luck\n");
		
	}
	return 0;
}


你可能感兴趣的:(编程,算法,百度,Google,ACM)