two-sat hdu3062 UVALive 3211

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的主要内容,如果未能解决你的问题,请参考以下文章

[HDU3062]Party

HDU 3062 && HDU 1824 && POJ 3578 && BZOJ 1997 2-SAT

HDU3062(2-SAT)

HDU 3062 Party

二分+2-sat——hdu3062

图论(2-sat):HDU 3062 Party