2749

/*
2SAT验证型题目,需要建图,2分加速
此种类型题目重在建图
*/

// include file
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <ctime>

#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <bitset>
#include <strstream>

#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <list>
#include <functional>

using namespace std;

// typedef
typedef long long LL;
typedef unsigned long long ULL;

// 
#define read freopen("in.txt","r",stdin)
#define write freopen("out.txt","w",stdout)
#define FORi(a,b) for(int i=(a);i<(b);i++)
#define FORj(a,b) for(int j=(a);j<(b);j++)

#define FF(i,a)    for(int i=0;i<(a);i+++)
#define FFD(i,a)   for(int i=(a)-1;i>=0;i--)
#define Z(a) (a<<1)
#define Y(a) (a>>1)

const double eps = 1e-11;
const double Pi = acos(-1.0);

template<class T> inline T sqr(T a){return a*a;}
template<class T> inline T TMAX(T x,T y)
{
	if(x>y) return x;
	return y;
}
template<class T> inline T TMIN(T x,T y)
{
	if(x<y) return x;
	return y;
}
template<class T> inline T MMAX(T x,T y,T z)
{
	return TMAX(TMAX(x,y),z);
}


// code begin
#define MAXN 5010

struct node
{
	int a,b;
};

node hate[MAXN];
node like[MAXN];
node pts[MAXN];
int dst[MAXN][3];
bool flag[510][510];

vector<int> G[MAXN];

int scc;
int cnt;
int used[MAXN];
int stk1[MAXN],top1;
int stk2[MAXN],top2;
int isin[MAXN];
int dfn[MAXN];
int low[MAXN];
int id[MAXN];
int N,A,B;
int sx1,sy1,sx2,sy2;
bool ok;

void gabow_scc(int i)
{
	used[i] = true;
	stk1[top1++] = i;
	stk2[top2++] = i;
	dfn[i] = cnt++;
	isin[i] = true;

	FORj( 0,G[i].size() )
	{
		if(!used[ G[i][j] ])
		{
			gabow_scc(G[i][j]);
		}
		else if(isin[G[i][j]])
		{
			while(dfn[stk2[top2-1]]>dfn[G[i][j]])
				top2--;
		}
	}

	if(i==stk2[top2-1])
	{
		top2--;
		int w;
		do
		{
			w = stk1[--top1];
			isin[w] = false;
			id[w] = scc;
		}while(w!=i);

		scc++;
	}
}

void tarjan_scc(int i)
{
	used[i] = true;
	stk1[top1++] = i;
	dfn[i] = cnt;
	low[i] = cnt;
	cnt++;
	isin[i] = true;

	FORj(0,G[i].size())
	{
		if(!used[ G[i][j] ])
		{
			tarjan_scc(G[i][j]);
			low[i] = TMIN(low[i],low[G[i][j]]);
		}
		else if(isin[G[i][j]])
		{
			low[i] = TMIN(low[i],dfn[G[i][j]]);
		}
	}

	if(dfn[i]==low[i])
	{
		int w;
		do
		{
			w=stk1[--top1];
			isin[w] = false;
			id[w] = scc;
		}while(w!=i);
		scc++;
	}
}

void build_G(int ml)
{
	FORi(0,N*2)
	{
		G[i].clear();
	}
	
	int a,b;
	FORi(0,A)
	{//hate
		a = hate[i].a;
		b = hate[i].b;
		// 2*a   2*b
		// 2*a+1 2*b+1;
		//a0b1
		int l1 = dst[a][0]+dst[b][1]+abs(sx1-sx2)+abs(sy1-sy2);
		//a1b0
		int l2 = dst[a][1]+dst[b][0]+abs(sx1-sx2)+abs(sy1-sy2);
		
		if(l1<=ml && l2<=ml)
		{
			G[2*a].push_back(2*b+1);
			G[2*b+1].push_back(2*a);

			G[2*b].push_back(2*a+1);
			G[2*a+1].push_back(2*b);
		}
		else if(l1<=ml && l2>ml)
		{
			G[2*a+1].push_back(2*a);
			G[2*b].push_back(2*b+1);
		}
		else if(l1>ml && l2<=ml)
		{
			G[2*a].push_back(2*a+1);
			G[2*b+1].push_back(2*b);
		}
		else
		{
			ok = false;
			return;
		}
	}

	FORi(0,B)
	{//like
		a = like[i].a;
		b = like[i].b;
		// 2*a   2*b
		// 2*a+1 2*b+1;
		//a0b0
		int l1 = dst[a][0]+dst[b][0];
		//a1b1
		int l2 = dst[a][1]+dst[b][1];
		if(l1<=ml && l2<=ml)
		{
			G[2*a].push_back(2*b);
			G[2*b].push_back(2*a);
			G[2*a+1].push_back(2*b+1);
			G[2*b+1].push_back(2*a+1);
		}
		else if(l1<=ml && l2>ml)
		{
			G[2*a+1].push_back(2*a);
			G[2*b+1].push_back(2*b);
		}
		else if(l1>ml && l2<=ml)
		{
			G[2*a].push_back(2*a+1);
			G[2*b].push_back(2*b+1);
		}
		else
		{
			ok = false;
			return ;
		}
	}

	FORi(0,N)
	{
		FORj(i+1,N)
		{
			if(!flag[i][j])
			{
				a = i;
				b = j;
				// 2*a   2*b
				// 2*a+1 2*b+1
				int l00 = dst[a][0]+dst[b][0];
				int l11 = dst[a][1]+dst[b][1];
				int l01 = dst[a][0]+dst[b][1]+abs(sx1-sx2)+abs(sy1-sy2);
				int l10 = dst[a][1]+dst[b][0]+abs(sx1-sx2)+abs(sy1-sy2);
				
				// a0b0
				// a1b1
				// a0b1
				// a1b0
				// 16中情况 1 0 0 0
				if(l00>ml && l11<=ml && l01<=ml && l10<=ml)
				{
					// A or B = 1;
					G[2*a].push_back(2*b+1);
					G[2*b].push_back(2*a+1);
				}
				// 0100
				else if(l00<=ml && l11>ml && l01<=ml && l10<=ml)
				{
					// A and B = 0;
					G[2*a+1].push_back(2*b);
					G[2*b+1].push_back(2*a);
				}
				// 0010
				else if(l00<=ml && l11<=ml && l01>ml && l10<=ml)
				{
					G[2*a].push_back(2*b);
					G[2*b+1].push_back(2*a+1);
				}
				// 0001
				else if(l00<=ml && l11<=ml && l01<=ml && l10>ml)
				{
					G[2*b].push_back(2*a);
					G[2*a+1].push_back(2*b+1);
				}
				// 1100
				else if(l00>ml && l11>ml && l01<=ml && l10<=ml)
				{
					// A XOR B = 1;
					G[2*a].push_back(2*b+1);
					G[2*b+1].push_back(2*a);
					G[2*b].push_back(2*a+1);
					G[2*a+1].push_back(2*b);
				}
				// 1010
				else if(l00>ml && l11<=ml && l01>ml && l10<=ml)
				{
					G[2*a].push_back(2*a+1);
				}
				// 1001
				else if(l00>ml && l11<=ml && l01<=ml && l10>ml)
				{
					G[2*b].push_back(2*b+1);
				}
				// 0110
				else if(l00<=ml && l11>ml && l01>ml && l10<=ml)
				{
					G[2*b+1].push_back(2*b);
				}
				// 0101
				else if(l00<=ml && l11>ml && l01<=ml && l10>ml)
				{
					G[2*a+1].push_back(2*a);
				}
				// 0011
				else if(l00<=ml && l11<=ml && l01>ml && l10>ml)
				{
					G[2*a].push_back(2*b);
					G[2*b].push_back(2*a);
					G[2*a+1].push_back(2*b+1);
					G[2*b+1].push_back(2*a+1);
				}
				// 1110
				else if(l00>ml && l11>ml && l01>ml && l10<=ml)
				{
					G[2*a].push_back(2*a+1);
					G[2*b+1].push_back(2*a);
				}
				// 1101
				else if(l00>ml && l11>ml && l01<=ml && l10>ml)
				{
					G[2*a+1].push_back(2*a);
					G[2*b].push_back(2*b+1);
				}
				// 1011
				else if(l00>ml && l11<=ml && l01>ml && l10>ml)
				{
					G[2*a].push_back(2*a+1);
					G[2*b].push_back(2*b+1);
				}
				// 0111
				else if(l00<=ml && l11>ml && l01>ml && l10>ml)
				{
					G[2*a+1].push_back(2*a);
					G[2*b+1].push_back(2*b);
				}
				// 1111
				else if(l00>ml && l11>ml && l01>ml && l10>ml)
				{
					ok = false;
					return;
				}

			}
		}
	}
}

bool SAT(int mid)
{

	memset(used,0,sizeof(used));
	memset(id,0,sizeof(id));
	top1 = top2 = 0;
	cnt = 1;
	scc = 1;
	memset(isin,0,sizeof(isin));
	memset(dfn,0,sizeof(dfn));
	memset(low,0,sizeof(low));
	FORi(0,N*2)
	{
		if(!used[i])
		{
			//gabow_scc(i);
			tarjan_scc(i);
		}
	}

	FORi(0,N)
	{
		if(id[2*i]==id[2*i+1])
			return false;
	}
	return true;
}

int main()
{
	read;
	write;
	while(scanf("%d %d %d",&N,&A,&B)!=-1)
	{
		scanf("%d %d %d %d",&sx1,&sy1,&sx2,&sy2);
		int a,b,Max=0;
		memset(flag,0,sizeof(flag));
		FORi(0,N)
		{
			scanf("%d %d",&pts[i].a,&pts[i].b);
			dst[i][0] = abs(sx1-pts[i].a)+abs(sy1-pts[i].b);
			dst[i][1] = abs(sx2-pts[i].a)+abs(sy2-pts[i].b);
			if( dst[i][0]>Max) Max=dst[i][0];
			if( dst[i][1]>Max) Max=dst[i][1];
		}

		FORi(0,A)
		{
			scanf("%d %d",&hate[i].a,&hate[i].b);
			hate[i].a--;
			hate[i].b--;
			flag[hate[i].a][hate[i].b] = 1;
			flag[hate[i].b][hate[i].a] = 1;
		}

		FORi(0,B)
		{
			scanf("%d %d",&like[i].a,&like[i].b);
			like[i].a--;
			like[i].b--;
			flag[like[i].a][like[i].b]=1;
			flag[like[i].b][like[i].a]=1;
		}
		
		Max*=2;
		Max += abs(sx1-sx2)+abs(sy1-sy2)+1;
		int L=0,R=Max,ans=Max;
		while(L<R)
		{
			//printf("L:%d R:%d\n",L,R);
			int mid=Y(L+R);
			ok = true;
			build_G(mid);
			if(ok&&SAT(mid))
			{
				if(mid<ans) ans=mid;
				R=mid;
			}
			else
				L=mid+1;
		}
		if(ans!=Max) printf("%d\n",ans);
		else printf("-1\n");
	}
	return 0;
}
posted @ 2011-03-01 11:09  AC2012  阅读(210)  评论(0编辑  收藏  举报