HDOJ 1814 - Peaceful Commission 输出字典序最小的2-sat方案...暴力2-sat

来源:互联网 发布:淘宝退货支付运费 编辑:程序博客网 时间:2024/06/05 20:30
          题意
                  有N个政党..每个政党两个议员..现在要组建一个和平委员会..每个政党派出一个议员..而某些议员之间是有冲突的..他们不能同时出现在和平委员会中..问是否存在方案使得和平委员会顺利组建?如果有请输出字典序最小的一种...
          题解

                   这个字典序最小太恶心了..我开始用强联通分量..然后拓扑..无论怎么调整都找不到正确输出字典序最小的方法..最后直接暴力解决..暴力染色..


program:

#include<iostream>#include<stdio.h>#include<cmath>#include<queue>#include<stack>#include<string.h>#include<map>#include<set>#include<algorithm>#define oo 1000000007#define MAXN 8005#define MAXM 20005#define ll long longusing namespace std;  struct node{       int x,y,next;}line[MAXM<<1];int n,last,Lnum,_next[MAXN<<1],num,way[MAXN<<1],color[MAXN<<1];bool instack[MAXN<<1];stack<int> mystack;void addline(int x,int y){       line[++Lnum].next=_next[x],_next[x]=Lnum,line[Lnum].x=x,line[Lnum].y=y;}bool dfs(int x){        if(color[x]==2) return false;        if(color[x]==1) return true;        color[x]=1,color[x^1]=2;        way[num++]=x;        for(int k=_next[x];k;k=line[k].next)           if(!dfs(line[k].y)) return false;         return true;  }    bool find(){        memset(color,0,sizeof(color));        for(int i=0;i<(n<<1);i++)      {               if(color[i]) continue;              num=0;              if(!dfs(i))            {                   for(int j=0;j<num;j ++) color[way[j]]=color[way[j]^1]=0;                       if(!dfs(i^1))return false;             }      }        return true;  }  int main(){           int i,m;          while (~scanf("%d%d",&n,&m))       {              memset(_next,0,sizeof(_next));              Lnum=0;              while (m--)              {                     int x,y;                     scanf("%d%d",&x,&y),x--,y--;                     addline(x,y^1),addline(y,x^1);              }               if (!find()) printf("NIE\n");              else              {                          for (i=0;i<(n<<1);i++)                        if (color[i]==1) printf("%d\n",i+1);              }       }       return 0;}