Peaceful Commission

这道题题意就是给你n对人,一对中编号为x,x+1,给你m对矛盾,表示这两个人不能同时选。

然后就是Two-Sat的模板题了,就是根据对称性,连边,加缩点,最后拓扑排序,求出一组可行解就可以了。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<queue>
  6 #include<cstring>
  7
  8 using namespace std;
  9
 10 typedef pair<int,int>pai;
 11 const int NN=8007,MM=20007,INF=1e9+7;
 12
 13 bool flag=0;
 14 int n,m;
 15 int cnt=0,head[NN*2],next[MM*2],rea[MM*2],cntr=0,headr[NN*2],nextr[MM*2],rear[MM*2];
 16 int Time,top,low[NN*2],dfn[NN*2],minnum[NN*2],stack[NN*2],instack[NN*2];
 17 int sz,belong[NN*2];
 18 int fan[NN*2],ru[NN*2];
 19 queue<int>ve[NN*2];
 20
 21 struct Node
 22 {
 23     int x,y;
 24 }a[MM];
 25
 26 void add(int u,int v)
 27 {
 28     cnt++;
 29     next[cnt]=head[u];
 30     head[u]=cnt;
 31     rea[cnt]=v;
 32 }
 33 void add2(int u,int v)
 34 {
 35     cntr++;
 36     nextr[cntr]=headr[u];
 37     headr[u]=cntr;
 38     rear[cntr]=v;
 39 }
 40 void Tarjan(int u)
 41 {
 42     dfn[u]=low[u]=++Time;
 43     stack[++top]=u,instack[u]=true;
 44     for (int i=head[u];i!=-1;i=next[i])
 45     {
 46         int v=rea[i];
 47         if (dfn[v]==0)
 48         {
 49             Tarjan(v);
 50             low[u]=min(low[v],low[u]);
 51         }
 52         else if (instack[v]) low[u]=min(low[u],dfn[v]);
 53     }
 54     if (low[u]==dfn[u])
 55     {
 56         int x=-1;
 57         minnum[++sz]=INF;;
 58         while (!ve[sz].empty()) ve[sz].pop();
 59         while (x!=u)
 60         {
 61             x=stack[top--];
 62             belong[x]=sz;
 63             minnum[sz]=min(minnum[sz],x);//记录最小编号,发现对称的那个环的最小编号应该是该环最小编号的fan
 64             ve[sz].push(x);
 65             instack[x]=false;
 66         }
 67     }
 68 }
 69 void rebuild()
 70 {
 71     for (int i=1;i<=2*n;i++)
 72         for (int j=head[i];j!=-1;j=next[j])
 73         {
 74             int v=rea[j];
 75             if (belong[i]!=belong[v])
 76             {
 77                 ru[belong[v]]++;
 78                 add2(belong[i],belong[v]);
 79             }
 80         }//重构
 81 }
 82 bool cmp(int x,int y)
 83 {
 84     return x<y;
 85 }
 86 void solve()
 87 {
 88     int ans[NN*2];
 89     queue<int>q;
 90     while (!q.empty()) q.pop();
 91     for (int i=1;i<=sz;i++)
 92         if (!ru[i]) q.push(i);
 93     bool biao[NN*2]={0};
 94     top=0;
 95     while(!q.empty())
 96     {
 97         int u=q.front();
 98         if (!biao[fan[minnum[u]]]) ans[++top]=u,biao[minnum[u]]=1;
 99         q.pop();
100         for (int i=headr[u];i!=-1;i=nextr[i])
101         {
102             int v=rear[i];
103             ru[v]--;
104             if (!ru[v]) q.push(v);
105         }
106     }//拓扑的一个过程
107     bool booo=0;
108     int res[NN],ll=0;
109     for (int i=1;i<=top;i++)
110     {
111         int x=ans[i];
112         while(!ve[x].empty())
113         {
114             res[++ll]=ve[x].front();
115             ve[x].pop();
116         }
117     }//ll最终等于n
118     sort(res+1,res+ll+1,cmp);
119     for (int i=1;i<=ll;i++)
120         printf("%d\n",res[i]);
121 }
122 void init()
123 {
124     cntr=cnt=top=Time=sz=flag=0;
125     memset(dfn,0,sizeof(dfn));
126     memset(head,-1,sizeof(head));
127     memset(headr,-1,sizeof(headr));
128     memset(ru,0,sizeof(ru));
129     for (int i=1;i<=2*n;i++)
130         if (i%2==1) fan[i]=i+1;
131         else fan[i]=i-1;
132     for (int i=1;i<=m;i++)
133     {
134         scanf("%d%d",&a[i].x,&a[i].y);
135         add(fan[a[i].y],a[i].x);
136         add(fan[a[i].x],a[i].y);//刚开始连反向边并不影响正确率,而且在拓扑的时候不需要反向标记,方便许多。
137     }
138 }
139 void pan()
140 {
141     for (int i=1;i<=2*n;i+=2)
142         if (belong[i]==belong[fan[i]])//如果一个块中,有编号一组的点,绝对不可以满足。
143         {
144             flag=1;
145             return;
146         }
147 }
148 int main()
149 {
150     while (~scanf("%d%d",&n,&m))
151     {
152         init();//初始化非常重要。
153         for (int i=1;i<=n*2;i++)
154             if (dfn[i]==0) Tarjan(i);//tarjan一次
155         pan();
156         if (flag)
157         {
158             printf("NIE\n");
159             continue;
160         }
161         rebuild();
162         solve();
163     }
164 }
时间: 2024-10-24 11:16:00

Peaceful Commission的相关文章

HDU 1814 Peaceful Commission

Peaceful Commission Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 181464-bit integer IO format: %I64d      Java class name: Main The Public Peace Commission should be legislated in Parliament of The Democra

hdu 1814 Peaceful Commission (2-sat 输出字典序最小路径)

Peaceful Commission Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1948    Accepted Submission(s): 560 Problem Description The Public Peace Commission should be legislated in Parliament of Th

HDOJ 1814 Peaceful Commission

经典2sat裸题,dfs的2sat能够方便输出字典序最小的解... Peaceful Commission Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1578    Accepted Submission(s): 406 Problem Description The Public Peace Commission should

hdoj1814 Peaceful Commission【2-set】

题目:hdoj1814 Peaceful Commission 讲解:这里 这是这个题目要输出字典序最小的解,刚好第一种暴力的解法输出来的就是原题目的解,因为每次染色的时候先染字典序小的,所以肯定对. AC代码: #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <cmath> #include <stack> #in

HDU 1814 Peaceful Commission(2-sat)

HDU 1814 Peaceful Commission 题目链接 题意: 根据宪法,Byteland民主共和国的公众和平委员会应该在国会中通过立法程序来创立. 不幸的是,由于某些党派代表之间的不和睦而使得这件事存在障碍. 此委员会必须满足下列条件: 每个党派都在委员会中恰有1个代表, 如果2个代表彼此厌恶,则他们不能都属于委员会. 每个党在议会中有2个代表.代表从1编号到2n. 编号为2i-1和2i的代表属于第I个党派. 任务 写一程序: 从文本文件读入党派的数量和关系不友好的代表对, 计算决

hdu1814 Peaceful Commission

hdu1814 Peaceful Commission 题意:2-sat裸题,打印字典序最小的 我写了三个 染色做法,正解 scc做法,不管字典序 scc做法,错误的字典序贪心 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int N = 2e4+5,

HDU 1814 Peaceful Commission(2-sat 模板题输出最小字典序解决方式)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1814 Problem Description The Public Peace Commission should be legislated in Parliament of The Democratic Republic of Byteland according to The Very Important Law. Unfortunately one of the obstacles is t

HDU 1814 Peaceful Commission(2-sat 模板题输出最小字典序解)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1814 Problem Description The Public Peace Commission should be legislated in Parliament of The Democratic Republic of Byteland according to The Very Important Law. Unfortunately one of the obstacles is t

【HDU】1814 Peaceful Commission

http://acm.hdu.edu.cn/showproblem.php?pid=1814 题意:n个2人组,编号分别为2n和2n+1,每个组选一个人出来,且给出m条关系(x,y)使得选了x就不能选y,问是否能从每个组选出1人.且输出字典序最小的答案.(n<=8000, m<=20000) #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #in