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的主要内容,如果未能解决你的问题,请参考以下文章