首页 > 代码库 > two-sat hdu3062 UVALive 3211

two-sat hdu3062 UVALive 3211

2-sat就是给定形如 x=xval or y=yval的若干约数,求是否存在全部满足。

这是一种dfs的算法,参考大白书

hdu3062 基本上是模板题吧,xval和yval都告诉你了。

#include<bits/stdc++.h>using namespace std;const int N=(int)2e3+10;int n,m;int mark[N],s[N],top=0;vector<int> g[N];bool dfs(int x) {	if(mark[x^1]) return 0;if(mark[x]) return 1;	mark[x]=1;s[++top]=x;	for(auto v:g[x]) if(!dfs(v)) return 0;	return 1;}void add(int x,int xval,int y,int yval) {	x=x*2+xval,y=y*2+yval;	g[x^1].push_back(y),g[y^1].push_back(x);}bool solve() {	for(int i=0;i<2*n;i+=2) if(!mark[i]&&!mark[i^1]){		top=0;		if(!dfs(i)) {			for(int j=top;j>=1;j--) mark[s[j]]=0;top=0;			if(!dfs(i^1)) return 0;		}	}	return 1;}void in() {	for(int i=1;i<=m;i++) {		int u,v,t1,t2;		scanf("%d%d%d%d",&u,&v,&t1,&t2);		add(u,t1,v,t2);	}	puts(solve()?"YES":"NO");}main() {	while(~scanf("%d%d",&n,&m)){		for(int i=0;i<n*2;i++) g[i].clear();		memset(mark,0, sizeof(mark));memset(s,0,sizeof(s));in();	}		return 0;} 

 UVALive 3211

我们可以考虑二分答案,判断这个答案满不满足我们可以用2-sat

如何建图?我们枚举所有的点,如果x (0/1)-y(0/1) < mid (0/1为是begin or and)那么就可以转换成 x=(0/1)^1 or y=(0/1)^1

对此跑一边2-sat就行了。

#include<bits/stdc++.h>using namespace std;const int N =(int)3e3+10;struct Two_Sat {	int n;	int top=0;	int sta[N<<1];	vector<int> g[N<<1];	int mark[N<<1];	void init(int n) {		this->n=n;		for(int i=0;i<n*2;i++) g[i].clear();		memset(mark,0, sizeof(mark));	}		void add(int x,int xval,int y,int yval) {		x=x*2+xval,y=y*2+yval;		g[x^1].push_back(y),g[y^1].push_back(x);	}		bool dfs(int x) {		if(mark[x^1]) return 0;if(mark[x]) return 1;		sta[++top]=x;mark[x]=1;		for(auto v:g[x]) if(!dfs(v)) return 0;		return 1;	}		bool solve() {		for(int i=0;i<2*n;i+=2) if(!mark[i]&&!mark[i^1]) {			top=0;			if(!dfs(i)) {				for(int j=top;j>=1;j--) mark[sta[j]]=0;top=0;				if(!dfs(i^1)) return 0;			}		}		return 1;	}}WSM_AK;int Abs(int a){return a>0?a:-a;}int s[N][2],n;bool ok(int now) {	WSM_AK.init(n);	for(int i=1;i<=n;i++) for(int a=0;a<=1;a++)		for(int j=i+1;j<=n;j++) for(int b=0;b<=1;b++)		if(Abs(s[i][a]-s[j][b])<now) WSM_AK.add(i-1,a^1,j-1,b^1);	return WSM_AK.solve();}main() {		while(cin>>n&&n) {		int l=0,r=0;		for(int i=1;i<=n;i++) for(int k=0;k<=1;k++)		scanf("%d",&s[i][k]),r=max(r,s[i][k]);		while(l<r) {			int mid=l+(r-l+1)/2;			if(!ok(mid)) r=mid-1;//ans=mid;			else l=mid;		}		printf("%d\n",l);	}		return 0;} 

 

two-sat hdu3062 UVALive 3211