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;
}
时间: 2024-08-26 10:26:47

two-sat hdu3062 UVALive 3211的相关文章

UVALive - 3211 (2-SAT + 二分)

layout: post title: 训练指南 UVALive - 3211 (2-SAT + 二分) author: "luowentaoaa" catalog: true mathjax: true tags: - 2-SAT - 图论 - 训练指南 Now or later UVALive - 3211 题意 n架飞机,每架可选择两个着落时间.安排一个着陆时间表,使得着陆间隔的最小值最大 题解 二分查找最大值P,每次都用2-SAT判断是否可行. #include<bits

UVALive - 3211 - Now or later(图论——2-SAT)

Problem   UVALive - 3211 - Now or later Time Limit: 9000 mSec Problem Description Input Output Sample Input 10 44 156 153 182 48 109 160 201 55 186 54 207 55 165 17 58 132 160 87 197 Sample Output 10 题解:2-SAT问题板子题,这个问题主要是理论难度比较大,有了结论之后代码很容易,有专门的论文阐释算

UVALive 3211 Now or later

Now or later Time Limit: 9000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ID: 321164-bit integer IO format: %lld      Java class name: Main As you must have experienced, instead of landing immediately, an aircraft someti

UVALive - 3211 Now or later (2-SAT)

题目大意:有n架飞机需要着陆.每架飞机有两种选择,早着陆或者晚着陆,二选其一 现在为了保证飞机的着陆安全,要求两架着陆的飞机的时间间隔的最小值达到最大 解题思路:最小值最大,二分枚举 设第i架飞机选择着陆方式为a,第j架飞机选择着陆的方式为b,枚举的时间间隔为mid 如果abs(plane[i][a] - plane[j][b]) < mid,表明这两架飞机以这样的着陆方式是矛盾的,所以只能二选其一,这样,关系式就推出来了 链式前向星 #include <cstdio> #include

UVALive 3211 Now or later(2-SAT,二分,Kosaraju)

题意:有n个飞机要降落,每机都可以在两个时间点上选择降落.但是两机的降落时间间隔太小会影响安全性,所以,要求两机的降落时间应该达到最大,当然也不能冲突了.问最大的时间间隔是多少?(其实问的是max(每种方案中两机间的最小间隔) ) 思路: 用Kosaraju算法也是可以过的,而且代码也比较少,那就用此法解决了. 主要的步骤是: 二分穷举每个时间间隔,对于每个间隔,建反向图,对图进行DFS着色看是否有冲突,无冲突的话证明此间隔是可以实现的.要找一个可以实现的,且间隔最大的. 1 #include

{TwoSAT}

今天学习图论的时候,碰到了2sat问题 虽然不是很难理解,感觉很精妙 ▄█?█● 用的LRJ白书上的模板. 套路如下:  2 - SAT就是2判定性问题,是一种特殊的逻辑判定问题. 选择的置为1,未选的置为0 对于2SAT,每组矛盾都会有四种情况(2*2),题目会限制一种不成立,我们要做的就是找出这一种,用逻辑连接词表示出来,然后取反,加边即可. 具体过程白书上p324有讲,这里就不说了. 下面附三道题,做做就知道套路了 Party HDU - 3062 1 #include <bits/std

LA 3211 飞机调度(2—SAT)

https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间为E,晚着陆时间为L,不得在其他时间着陆.你的任务是为这些飞机安排着陆方式,使得整个着陆计划尽量安全.换句话说,如果把所有飞机的实际着陆时间按照从早到晚的顺序排列,相邻两个着陆时间间隔的最小值. 思路: 二分查找最大值P,每次都用2—SAT判断是否可行. 1 #include<iostream>

LA 3211

As you must have experienced, instead of landing immediately, an aircraft sometimes waits in a holding loop close to the runway. This holding mechanism is required by air traffic controllers to space apart aircraft as much as possible on the runway (

UVALive 4848 Tour Belt

F - Tour Belt Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 4848 Description Korea has many tourist attractions. One of them is an archipelago (Dadohae in Korean), a cluster of small islands sca