poj 2749

2sat。邻接表会超时。

代码:

#include<iostream>
#include<fstream>
#include<cmath>
#include<vector>

using namespace std;

vector<int> edge[1001],edge2[1001];
int n;

int v[1001],low[1001],dfn[1001],stack[1001],scc[1001],tot,index,top;

void tarjan(int s){
	int i,j,k;
	dfn[s]=low[s]=++index;
	stack[++top]=s;
	v[s]=1;
	for(j=0;j<edge[s].size();j++)
	{
		k=edge[s][j];
		if(dfn[k]==0)
		{
			tarjan(k);
			low[s]=min(low[s],low[k]);
		}
		else
			if(v[k])
			{
				low[s]=min(low[s],dfn[k]);
			}
	
	}

	for(j=0;j<edge2[s].size();j++)
	{
		k=edge2[s][j];
		if(dfn[k]==0)
		{
			tarjan(k);
			low[s]=min(low[s],low[k]);
		}
		else
			if(v[k])
			{
				low[s]=min(low[s],dfn[k]);
			}
	
	}

	if(low[s]==dfn[s]){
		++tot;
		
		do{
			i=stack[top--];
			scc[i]=tot;
			v[i]=0;
		}while(i!=s);
	}
}



void solve(){
	int i,j,k;
	index=0;tot=0;top=0;

	memset(dfn,0,sizeof(dfn));
	for(i=1;i<=2*n;i++)
		if(dfn[i]==0)
			tarjan(i);
}

int a[1001],b[1001],c[1001],d[1001];
int n1,n2,xx1,yy1,xx2,yy2;
int xx[501],yy[501];
int mid;
int len1[501],len2[501],len;

void build(){
	int i,j,k;
	for(i=1;i<=2*n;i++)
		edge2[i].clear();
	for(i=1;i<=n;i++)
		for(j=i+1;j<=n;j++)
		{
			if(len1[i]+len1[j]>mid)
			{
			
				edge2[j].push_back(i+n);
			
				edge2[i].push_back(j+n);
	
			}
			if(len2[i]+len2[j]>mid)
			{
				
				edge2[j+n].push_back(i);
				
				edge2[i+n].push_back(j);
			}
			if(len1[i]+len2[j]+len>mid)
			{
			
				edge2[j+n].push_back(i+n);

			
				edge2[i].push_back(j);
			}
			if(len1[j]+len2[i]+len>mid)
			{
				
				edge2[i+n].push_back(j+n);
				
				edge2[j].push_back(i);
			}
		}

	
}	

void read(){
//	ifstream cin("in.txt");
	int i,j,k,s,max1=0,max2=0;
//	cin>>n>>n1>>n2;
	scanf("%d%d%d",&n,&n1,&n2);
//	cin>>xx1>>yy1>>xx2>>yy2;
	scanf("%d%d%d%d",&xx1,&yy1,&xx2,&yy2);
	for(i=1;i<=n;i++)
	{
//		cin>>xx[i]>>yy[i];
		scanf("%d%d",&xx[i],&yy[i]);
		len1[i]=abs(xx[i]-xx1)+abs(yy[i]-yy1);
		max1=max(max1,len1[i]);
		len2[i]=abs(xx[i]-xx2)+abs(yy[i]-yy2);
		max2=max(max2,len2[i]);
	}
	for(i=1;i<=n1;i++)
//		cin>>a[i]>>b[i];
		scanf("%d%d",&a[i],&b[i]);
	for(i=1;i<=n2;i++)
		scanf("%d%d",&c[i],&d[i]);
//		cin>>c[i]>>d[i];
	
	for(i=1;i<=n1;i++)
	{
	
		edge[b[i]+n].push_back(a[i]);
	
		edge[b[i]].push_back(a[i]+n);

		
		edge[a[i]+n].push_back(b[i]);
		
		edge[a[i]].push_back(b[i]+n);
	}
	for(i=1;i<=n2;i++)
	{
	
		edge[d[i]].push_back(c[i]);
	
		edge[d[i]+n].push_back(c[i]+n);

	
		edge[c[i]].push_back(d[i]);
	
		edge[c[i]+n].push_back(d[i]+n);
	}
	len=abs(xx1-xx2)+abs(yy1-yy2);
	i=0;j=max1+max2+len;
	mid=j;
	build();
	solve();
	for(k=1;k<=n;k++)
		if(scc[k]==scc[k+n])
			break;
	if(k<=n){
		cout<<-1<<endl;
		return;
	}
	while(i<=j)
	{
		mid=(i+j)>>1;
		build();
		solve();
		for(k=1;k<=n;k++)
			if(scc[k]==scc[k+n])
				break;
		if(k<=n) i=mid+1;
		else
			j=mid-1;
	}

		cout<<i<<endl;

}

int main(){
	read();
	return 0;
}

posted on 2011-03-19 16:23  宇宙吾心  阅读(396)  评论(0)    收藏  举报

导航