Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

有人能帮忙看一下我写的3648的2-sat的代码?不知道那里错了,小弟在此先谢了。

Posted by 457 at 2009-10-21 22:00:25
//自己写的2—sat 
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
const int N=2000;
vector <int>vec[N];
vector <int>vecn[N];
vector <int>col[N];
bool vis[N],sit[N];
int id[N],order[N],ru[N],sat[N],stack[N],in[N],ans[N],ak[N];
int color,cnt,temp;
void initial(int n)
{
	for(int i=0;i<=n;i++)
	{
		vec[i].clear();
		vecn[i].clear();
		col[i].clear();
	}
}
void input(int n,int m)
{
	int x,y,i;
	char str[2][5];
	while(m--)
	{
		scanf("%d%s%d%s",&x,str[0],&y,str[1]);
		if(str[0][0]=='w') x=x*2+1;
		else	x=x*2;
		if(str[1][0]=='w') y=y*2+1;
		else	y=y*2;
		vec[x].push_back(y^1);
		vec[y].push_back(x^1);
		vecn[x^1].push_back(y);
		vecn[y^1].push_back(x);
	}
	for(i=1;i<n;i++)
	{
		vec[1].push_back(i*2);
		vec[1].push_back(i*2+1);
		vec[i*2].push_back(0);
		vec[i*2+1].push_back(0);
		vecn[i*2].push_back(1);
		vecn[i*2+1].push_back(1);
		vecn[0].push_back(i*2);
		vecn[0].push_back(i*2+1);
	}
}
void dfs(int x)
{
	int i,j;
	vis[x]=true;
	for(i=0;i<vec[x].size();i++)
	{
		j=vec[x][i];
		if(!vis[j])
		dfs(j);	
	}
	order[cnt++]=x;
}
void dfsn(int x)
{
	int i,j;
	vis[x]=true;
	id[x]=color;
	col[color].push_back(x);
	for(i=0;i<vecn[x].size();i++)
	{
		j=vecn[x][i];
		if(!vis[j])
		dfsn(j);
		if(id[j]!=id[x])
		ru[id[x]]++;//求出每个强连通分量的入度 
	}
}
void Kosaraju(int n)
{
	int i,j,k,t;
	memset(ru,0,sizeof(ru));
	memset(vis,false,sizeof(vis));
	memset(id,-1,sizeof(id));
	color=1;cnt=0;
	for(i=0;i<=n;i++)
		if(!vis[i])
			dfs(i);
	memset(vis,false,sizeof(vis));
	temp=-2;
	for(i=cnt-1;i>=0;i--)
	{
		if(!vis[order[i]])
		{
			if(id[order[i]^1]!=-1)
			color=id[order[i]^1]^1;
			else
			{
				temp+=2;
				color=temp;
			}
			dfsn(order[i]);	
		}
	}
}
bool check(int n)
{
	int j=0;
	for(int i=0;i<n;i++)
	{
		if(id[j]==id[j^1])
		return false;
		j+=2;
	}
	return true;
} 
int tor_sort(int n)//拓扑排序 
{
	int top=0,i,j,num=0;
	memset(in,false,sizeof(in));
	while(1)
	{
		bool flag=true;
		for(i=0;i<=n;i++)
		{
			if(ru[id[i]]==0&&!in[i])
			{
				num++;
				flag=false;
				in[i]=true;
				stack[++top]=i;
				for(j=0;j<vec[i].size();j++)
				{
					int v=vec[i][j];
					ru[id[v]]--;
				}
			}
		}
		if(flag) break;
	}
	return top;
}
void find(int x)
{
	int i;
	for(i=0;i<vec[x].size();i++)
	{
		int v=vec[x][i];
		if(!vis[id[v]])
		{
			vis[id[v]]=true;
			ak[++ak[0]]=id[v];
			vis[id[v^1]]=true;
		}
		if(!sit[v])
		{
			sit[v]=true;
			sit[v^1]=true;
			find(v);
		}
	}
}
void get_ans(int n)
{
	memset(vis,false,sizeof(vis));
	memset(sit,false,sizeof(sit));
	int top=tor_sort(n);
	ak[0]=0;	
	for(int i=top;i>0;i--)
	{
		int v=stack[i];
		if(!vis[id[v]])
		{
			ak[++ak[0]]=id[v];
			vis[id[v]]=true;
			vis[id[v^1]]=true;
			sit[v]=true;
			sit[v^1]=true;
			find(v);
		}
	}
	ans[0]=0;
	for(int i=1;i<=ak[0];i++)
		for(int j=0;j<col[ak[i]].size();j++)
		ans[++ans[0]]=col[ak[i]][j];
}
int main()
{
	int Cas,n,m;
	while(scanf("%d%d",&n,&m)!=EOF)//有n对顶点,有m个对立关系 
	{
		if(n==0&&m==0) break;
		initial(2*n-1);//初始化
		input(n,m);//输入构图,Ai向Aj'连,则Aj向Ai‘连,均为有向边。
		Kosaraju(2*n-1);//求强连通分量
		if(!check(n))
		{
			printf("bad luck\n");
			continue;
		}
		get_ans(2*n-1);
		sort(ans+1,ans+ans[0]+1);
		for(int i=2;i<=ans[0];i++)
		{
			if(i!=2) printf(" ");
			if(ans[i]%2==0) printf("%dw",ans[i]/2);
			else printf("%dh",ans[i]/2);	
		}
		printf("\n");
	}
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator