hdu-1814(2-sat)
Posted huangdao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu-1814(2-sat)相关的知识,希望对你有一定的参考价值。
题意:给你n个组,m条规则,每组有俩个人,这两个人不能同时出现,然后m条规则代表着有两个人,这两个人也不能同时出现,问你是否存在每组都能出现一人的选择方案
解题思路:因为这个需要字典序输出,所以只能用暴力的方法解决,如果x,y在同一条规则里面,那么建立一条边由x指向和y同一组的另一个人,y也这样做,然后开始暴力dfs
代码:
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<queue> #include<vector> #define oth(x) (x%2==0?x-1:x+1) using namespace std; const int maxn=20050; int n,m,cnt; bool mark[maxn]; vector<int>e[maxn]; int ans[maxn]; bool dfs(int x) { if(mark[oth(x)]) return false; if(mark[x]) return true; mark[x]=true; ans[++cnt]=x; for(int i=0;i<e[x].size();i++) if(!dfs(e[x][i])) return false; return true; } bool twosat() { memset(mark,0,sizeof(mark)); for(int i=1;i<=n;i+=2) { if(!mark[i]&&!mark[oth(i)]) { cnt=0; if(!dfs(i)) { for(int j=1;j<=cnt;j++) mark[ans[j]]=mark[oth(ans[j])]=0; if(!dfs(oth(i))) return false; } } } return true; } int main() { int x,y; while(scanf("%d%d",&n,&m)!=EOF) { n=n*2; for(int i=0;i<=n;i++) e[i].clear(); for(int i=1;i<=m;i++) { cin>>x>>y; e[x].push_back(oth(y)); e[y].push_back(oth(x)); } if(twosat()) { for(int i=1;i<=n;i+=2) { if(mark[i]) printf("%d ",i); else printf("%d ",i+1); } } else printf("NIE "); } }
以上是关于hdu-1814(2-sat)的主要内容,如果未能解决你的问题,请参考以下文章
hdu1814Peaceful Commission(2-SAT)
HDU1814 Peaceful Commission 2-sat