Hoj 1917 Peaceful Commission
来源:互联网 发布:linux删除进程命令 编辑:程序博客网 时间:2024/06/03 22:47
题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=1917
2-sat问题。
如果a和b矛盾,那么a向b的反面连一条线。
以此建立了一颗有向图,然后对此图求强连通分量后缩点,反向连线后形成一个DAG图。
然后对此图求拓扑排序即可。
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <stack>#include <queue>#include <algorithm>#include <iostream>using namespace std;#define Maxn (8005 * 2)#define Maxm (40005 * 2)struct Edge{int a,b;}edge[Maxm],rEdge[Maxm];int first[Maxn],next[Maxm];int rFirst[Maxn],rNext[Maxm];int total,rTotal;//scc相关int sccno[Maxn];bool instack[Maxn];int dfn[Maxn];int low[Maxn];int dfs_clock;int scc_cnt;stack <int> st;//2sat相关int in[Maxn];int conflict[Maxn];int col[Maxn];int ans[Maxn];void addEdge(int a,int b){edge[total].a = a,edge[total].b = b;next[total] = first[a];first[a] = total++;}void addREdge(int a,int b){rEdge[rTotal].a = a,rEdge[rTotal].b = b;rNext[rTotal] = rFirst[a];rFirst[a] = rTotal++;}void init(){total = 0;memset(first,-1,sizeof(first));}void rInit(){rTotal = 0;memset(rFirst,-1,sizeof(rFirst));}void tarjan(int u){ dfn[u] = low[u] = ++dfs_clock; st.push(u); instack[u] = true; for(int i=first[u];i!=-1;i=next[i]) { int v = edge[i].b; if(!dfn[v]) { tarjan(v); low[u] = min(low[u],low[v]); } else if(instack[v]) { low[u] = min(low[u],dfn[v]); } } if(dfn[u] == low[u]) { scc_cnt++; while(1) { int v = st.top(); st.pop(); instack[v] = false; sccno[v] = scc_cnt; if(u == v) break; } }}void find_scc(int start,int n){scc_cnt = dfs_clock = 0;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low)); memset(instack,false,sizeof(instack)); while(!st.empty()) { st.pop(); } for(int i=start;i<=n;i++) { if(!dfn[i]) tarjan(i); }}bool twoSet(int start,int n){find_scc(start,n);for(int i=start;i<=n;i++){if(sccno[i] == sccno[i^1]) return false;}for(int i=start;i<=n;i++){conflict[sccno[i]] = sccno[i^1];conflict[sccno[i^1]] = sccno[i];}memset(in,0,sizeof(in));memset(col,0,sizeof(col));memset(ans,0,sizeof(ans));for(int i=start;i<=n;i++){for(int j=first[i];j!=-1;j=next[j]){int v = edge[j].b;if(sccno[i]!=sccno[v]){addREdge(sccno[v],sccno[i]);in[sccno[i]]++;}}}queue <int> q;for(int i=1;i<=scc_cnt;i++){if(in[i]==0) q.push(i);}while(!q.empty()){int u = q.front();q.pop();if(col[u] == 0) col[u] = 1,col[conflict[u]] = -1;for(int i=rFirst[u];i!=-1;i=rNext[i]){int v = rEdge[i].b;in[v]--;if(in[v]==0) q.push(v);}}for(int i=start;i<=n;i++){if(col[sccno[i]] == 1) ans[i] = 1;}return true;}int main(){#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);#endifint n,m;int a,b;while(scanf(" %d %d",&n,&m)!=EOF){init(),rInit();for(int i=1;i<=m;i++){scanf(" %d %d",&a,&b);a--;b--;addEdge(a,b^1);addEdge(b,a^1);}if(!twoSet(0,2*n-1)) {puts("NIE");continue;}for(int i=0;i<2*n;i++){if(ans[i]) printf("%d\n", i+1);}}return 0;}
- Hoj 1917 Peaceful Commission
- HOJ 1917 Peaceful Commission
- HOJ 1917 POI 2001 Peaceful Commission 2-SAT问题
- 2-sat hoj 和平委员会 Peaceful Commission
- hit 1917 && hdu 1814 Peaceful Commission
- [hit 1917] Peaceful Commission(2-sat)
- HDU 1814 Peaceful Commission / HIT 1917 Peaceful Commission /CJOJ 1288 和平委员会
- HDOJ 1814 Peaceful Commission
- hdu 1814 Peaceful Commission
- HDU1814 Peaceful Commission
- HDU 1814 Peaceful Commission
- hdu1814 Peaceful Commission--dfs
- HDU 1814 Peaceful Commission
- 【HIT1917】 Peaceful Commission
- Peaceful Commission HDU
- hdu1814 Peaceful Commission,2-sat
- hdu1814 Peaceful Commission 2-sat
- hdoj1814 Peaceful Commission【2-set】
- ^ shell
- 130821创建索引
- MDI窗体的优化---上
- POj 3601 Tower of Hanoi 汉诺塔(贪心)
- oracle 锁粒度
- Hoj 1917 Peaceful Commission
- HTML5_Canvas_属性、定义及方法
- ETL错误
- C++书籍
- 编程原则
- struts2常见错误总结
- 黑马程序员-------关于里氏替换原则、类型转换
- 构造函数和析构函数能否声明为虚函数?
- 通过popToViewController跳到任意navigation的具体页面