标签:while log 基本 bool 告诉 auto sizeof return abs
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;
}
标签:while log 基本 bool 告诉 auto sizeof return abs
原文地址:http://www.cnblogs.com/foreverpiano/p/2_sat.html