您的位置:首页 > 其它

HDU 1814 Peaceful Commission (最小字典序 2-SAT)

2017-07-20 10:23 501 查看

思路:

因为要解决最小最小字典序的问题,所以经典的2-SAT解决方法就没用了。。。只能暴力dfs。。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string.h>
#include <queue>
using namespace std;

const int maxn = 8010*2;
struct edge{
int to,v,next;
}ed[maxn*4];
int head[maxn],cnte = 0;
void ae(int x,int y){//addedge
ed[++cnte].to = y;
ed[cnte].next=head[x];
head[x]=cnte;
}
int n,m;
int col[maxn];
int pre[maxn];int cntp = 0;
//判断x点能不能选 因为x点能不能选需要选后边的点来试。。
bool dfs(int x){
if(col[x]==1) return true;
if(col[x^1]==1) return false;
col[x]=1,col[x^1]=-1;
pre[cntp++]=x;
for(int i=head[x];i!=-1;i=ed[i].next){
int to = ed[i].to;
if(!dfs(to)){
return false;
}
}
return true;
}
bool solve(){
for(int i = 0;i < 2*n;i+=2){
cntp = 0;
if(!dfs(i)){//如果第一个点选不了
for(int j=0;j<cntp;j++){
col[pre[j]] = col[pre[j]^1] = 0;
}
if(!dfs(i+1)){//如果第二个点也选不了 无解
return false;
}
}
else{//选第一个点
col[i]=1,col[i^1]=-1;
}
}
return true;
}
int main(){
int flag = 0,a,b;
while(~scanf("%d%d",&n,&m)){
memset(head,-1,sizeof(head));
memset(col,0,sizeof(col));
cntp = 0,flag=0,cnte=0;
for(int i = 1;i <= m;i++){
scanf("%d%d",&a,&b);a--,b--;
ae(a,b^1);ae(b,a^1);
}
flag = solve();
for(int i = 0;i < 2*n && flag == 1;i++){
if(col[i]==1){
printf("%d\n",i+1);
}
}
if(flag == 0) printf("NIE\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: