poj 2749 Building roads 2-sat

题意:

给n个村庄的坐标和两个特殊点s1,s2的坐标,现在要将每个村庄连到s1或s2上,使n个村庄间的最大距离最小。

分析:

二分任意两村庄间的最大距离,用2-sat判断该最大距离是否可行,二分的时候可以顺便记录答案,不用等最后区间为空时再输出l或l-1。

代码:

//poj 2749
//sep9
#include <iostream>
#include <vector>
using namespace std;
const int maxN=1024;
const int maxL=4000000;
vector<int> g[maxN],ng[maxN];
int n,m,cnt,scc,vis[maxN],dfn[maxN];
int x1,y1,x2,y2;
int x[maxN],y[maxN];
int a,b;
int ap[maxN],aq[maxN],bp[maxN],bq[maxN];
int d[maxN],D;
void addegde(int u,int v)
{
	g[u].push_back(v);
	ng[v].push_back(u);
}

void dfs(int k)
{
	vis[k]=1;
	for(int i=g[k].size()-1;i>=0;--i)
		if(!vis[g[k][i]])
			dfs(g[k][i]);
	dfn[++cnt]=k;
}

void ndfs(int k)
{
	vis[k]=scc;
	for(int i=ng[k].size()-1;i>=0;--i)
		if(!vis[ng[k][i]])
			ndfs(ng[k][i]);
}
void kosaraju()
{
	memset(vis,0,sizeof(vis));
	cnt=0;
	for(int i=1;i<=2*n;++i)
		if(!vis[i])
			dfs(i);
	memset(vis,0,sizeof(vis));
	scc=0;
	for(int i=2*n;i>=1;--i)
		if(!vis[dfn[i]]){
			++scc;
			ndfs(dfn[i]);
		}
}

int two_sat(int dis)
{
	int i,j;
	for(i=1;i<=2*n;++i)
		g[i].clear(),ng[i].clear();
	for(i=1;i<=a;++i){
		int p=ap[i],q=aq[i];
		addegde(p,q+n);
		addegde(p+n,q);
		addegde(q,p+n);
		addegde(q+n,p);
	}
	for(i=1;i<=b;++i){
		int p=bp[i],q=bq[i];
		addegde(p,q);
		addegde(q,p);
		addegde(p+n,q+n);
		addegde(q+n,p+n);
	}
	for(i=1;i<=n;++i)
		for(j=i+1;j<=n;++j)
			if(i!=j){
				if(d[i]+d[j]>dis){
					addegde(i,j+n);
					addegde(j,i+n);
				}
				if(d[i]+d[j+n]+D>dis){
					addegde(j+n,i+n);
					addegde(i,j);
				}
				if(d[i+n]+d[j]+D>dis){
					addegde(i+n,j+n);
					addegde(j,i);
				}
				if(d[i+n]+d[j+n]>dis){
					addegde(i+n,j);
					addegde(j+n,i);
				}
			}
	kosaraju();
 	for(i=1;i<=n;++i)
		if(vis[i]==vis[i+n])
			return 0;
	return 1;
}

int main()
{
	int i,j;
	scanf("%d%d%d",&n,&a,&b);
	scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
	for(i=1;i<=n;++i)
		scanf("%d%d",&x[i],&y[i]);
	for(i=1;i<=n;++i){
		d[i]=abs(x[i]-x1)+abs(y[i]-y1);
		d[i+n]=abs(x[i]-x2)+abs(y[i]-y2);
	}
	D=abs(x1-x2)+abs(y1-y2);
	int p,q;
	for(i=1;i<=a;++i)
		scanf("%d%d",&ap[i],&aq[i]);
	for(i=1;i<=b;++i)
		scanf("%d%d",&bp[i],&bq[i]);
	int l=0,r=maxL,ans=-1;
	while(l<r){
		int mid=(l+r)/2;
		if(two_sat(mid)==0)
			l=mid+1;
		else
			r=mid,ans=mid;
	}
	printf("%d",ans);
	return 0;
}
  
时间: 2024-09-26 23:53:18

poj 2749 Building roads 2-sat的相关文章

HDU 1815, POJ 2749 Building roads(2-sat)

HDU 1815, POJ 2749 Building roads 题目链接HDU 题目链接POJ 题意: 有n个牛棚, 还有两个中转站S1和S2, S1和S2用一条路连接起来. 为了使得任意牛棚两个都可以有道路联通,现在要让每个牛棚都连接一条路到S1或者S2. 有a对牛棚互相有仇恨,所以不能让他们的路连接到同一个中转站.还有b对牛棚互相喜欢,所以他们的路必须连到同一个中专站. 道路的长度是两点的曼哈顿距离. 问最小的任意两牛棚间的距离中的最大值是多少? 思路:二分距离,考虑每两个牛棚之间4种连

poj 2749 Building roads (二分+拆点+2-sat)

Building roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6229   Accepted: 2093 Description Farmer John's farm has N barns, and there are some cows that live in each barn. The cows like to drop around, so John wants to build some ro

poj 2749 Building roads(2-sat)

Description Farmer John's farm has N barns, and there are some cows that live in each barn. The cows like to drop around, so John wants to build some roads to connect these barns. If he builds roads for every pair of different barns, then he must bui

POJ 2749 Building roads 2-sat+二分答案

把爱恨和最大距离视为限制条件,可以知道,最大距离和限制条件多少具有单调性 所以可以二分最大距离,加边+check 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<stack> 6 #define N 5010 7 #define INF 4000000 8 using namespace std; 9 int di

[poj] 2749 building roads

原题 2-SAT+二分答案! 最小的最大值,这肯定是二分答案.而我们要2-SATcheck是否在该情况下有可行解. 对于目前的答案limit,首先把爱和恨连边,然后我们n^2枚举每两个点通过判断距离来实现连边,然后跑2-SAT判断是否有可行解 O(n^2logn) 想起来和听起来都很难写,事实上还好吧- #include<cstdio> #include<algorithm> #include<stack> #include<cstring> #define

poj 3625 Building Roads

题目连接 http://poj.org/problem?id=3625 Building Roads Description Farmer John had just acquired several new farms! He wants to connect the farms with roads so that he can travel from any farm to any other farm via a sequence of roads; roads already conn

poj 3625 Building Roads 最小生成树(prime或kruskal+并查集)(算法归纳)

Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Description Farmer John had just acquired several new farms! He wants to connect the farms with roads so that he can travel from any farm to any other farm via a sequence of roads;

2-SAT入门 poj2749 Building roads

poj2749 Building roads http://poj.org/problem?id=2749 二分答案,以后构造布尔表达式. 相互讨厌是!((a and b)or(!a and !b) 化简得 (!a or !b)and(a or b) 相互喜欢是!(a and !b)or(!a and b) 化简得 (!a or b)and(a or !b) 然后枚举点对讨论一个点对和S1,S2相连会不会超过lim来添加限制. 一共有四种情况都差不多,比如都连到S1会超过lim,就添加!(!a

Building roads

Building roads Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 34 Accepted Submission(s): 13   Problem Description Farmer John's farm has N barns, and there are some cows that live in each barn.