poj 3648 2-SAT建图+topsort输出结果
来源:互联网 发布:最好用的编程软件 编辑:程序博客网 时间:2024/06/07 03:32
其实2-SAT类型题目的类型比较明确,基本模型差不多是对于n组对称的点,通过给出的限制条件建图连边,然后通过缩点和判断冲突来解决问题。要注意的是在topsort输出结果的时候,缩点后建图需要反向连边,然后输出就可以了。2-sat题型差不多。
题意:新娘新郎分别坐在长桌两边,n-1队夫妇来参加婚礼,要求:夫妇不能坐在同一边,通奸关系不能坐在同一边。输出新娘对面的序列。
思路:对称关系:夫妇,限制条件:通奸关系。基础2-sat问题,缩点找冲突topsort输出结果一气呵成。。。
代码:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define MAXN 2002int instack[MAXN],stack[MAXN],fa[MAXN],vis[MAXN],head[MAXN],first[MAXN];int dfn[MAXN],low[MAXN],in[MAXN],ans[MAXN],que[MAXN];int a[MAXN][2],b[MAXN][2],flag[MAXN],cf[MAXN],col[MAXN];int n,m,tot,scnt,time,tt,top,index;struct Edge{int v,next;}edge[MAXN*MAXN],e[MAXN*MAXN];void addedge(int u,int v){edge[tot].v=v;edge[tot].next=head[u];head[u]=tot++;}void adde(int u,int v){e[tt].v=v;e[tt].next=first[u];first[u]=tt++;}void tarjan(int u){instack[u]=1;stack[top++]=u;dfn[u]=low[u]=++index;int v;for(int i=head[u];i!=-1;i=edge[i].next){v=edge[i].v;if(!dfn[v]){tarjan(v);low[u]=min(low[u],low[v]);}else if(instack[v]){low[u]=min(low[u],dfn[v]);}}if(low[u]==dfn[u]){scnt++;do{v=stack[--top];instack[v]=0;fa[v]=scnt;}while(v!=u);}}void build(){for(int i=0;i<m;i++) //2*n的点{int t1,t2;char c,v;scanf("%d%c",&t1,&c);scanf("%d%c",&t2,&v);if(c=='h'&&v=='h'){addedge(t1+n,t2);addedge(t2+n,t1);}else if(c=='h'&&v=='w'){addedge(t1+n,t2+n);addedge(t2,t1);}else if(c=='w'&&v=='h'){addedge(t1,t2);addedge(t2+n,t1+n);}else if(c=='w'&&v=='w'){addedge(t1,t2+n);addedge(t2,t1+n);}}addedge(0,n);}void solve(){memset(dfn,0,sizeof(dfn));memset(instack,0,sizeof(instack));index=0;scnt=0;top=0;for(int i=0;i<2*n;i++){if(!dfn[i])tarjan(i);}}int check(){for(int i=0;i<n;i++){if(fa[i]==fa[i+n]) //冲突{return 0;}cf[fa[i]]=fa[i+n];cf[fa[i+n]]=fa[i];}return 1;}void topsort(){int head=1,tail=1;for(int i=1;i<=scnt;i++){if(in[i]==0){que[tail++]=i;}}int v;while(tail>head){int u=que[head];head++;if(col[u]==0) //对于未着色的点x,将x染成红色1,同时将与x矛盾的点cf[x]染成蓝色-1。{col[u]=1;col[cf[u]]=-1;}for(int i=first[u];i!=-1;i=e[i].next){v=e[i].v;if(--in[v]==0){que[tail++]=v;}}}memset(ans,0,sizeof(ans));for(int i=0;i<n;i++){if(col[fa[i]]==1){ans[i]=1;}}for(int i=1;i<n;i++){if(ans[i])printf("%dh ",i);elseprintf("%dw ",i);}printf("\n");}int main(){while(scanf("%d%d",&n,&m)!=EOF,(n||m)){memset(head,-1,sizeof(head));tot=0;memset(first,-1,sizeof(first));tt=0;build();solve();if(!check())printf("bad luck\n");else{memset(in,0,sizeof(in));memset(col,0,sizeof(col));for(int i=0;i<2*n;i++){int v;for(int j=head[i];j!=-1;j=edge[j].next){v=edge[j].v;if(fa[i]!=fa[v]){adde(fa[v],fa[i]);in[fa[i]]++;}}}topsort();}}return 0;}
- poj 3648 2-SAT建图+topsort输出结果
- [2-sat][topsort输出解] POJ 3648 Wedding
- POJ 3683 2-sat问题,不过要输出路径用topsort
- poj 3683 2-sat建图+拓扑排序输出结果
- POJ 3648 2-sat 输出解
- POJ 3648 Wedding(2-SAT+输出方案)
- poj 3648 2-sat输出一组解
- Poj 3648 Wedding (2-sat 输出方案)
- poj 3648 Wedding 2-SAT输出
- POJ 3648 Wedding(2-SAT + 输出方案)
- POJ 3648 Wedding(2-sat方案输出,4级)
- poj 3648 2-sat 输出任意一组解模板
- POJ 3648 Wedding (2-SAT+输出可行解)
- poj 3648 Wedding(2-sat--拓扑排序输出可行解)
- Wedding (poj 3648 2-SAT 输出任意一组解)
- poj 3648 wedding(2-sat 拓扑排序输出方案)
- POJ 3648 Wedding 2-sat输出一组解
- POJ 3648Wedding (2-SAT 输出路径)
- 实时性Hadoop
- UVA 590 Always on the run
- HDU 3681 Prison Break (二分答案+状压DP+bfs预处理)
- Tomcat集群配置
- c# 读取 Excel的内容
- poj 3648 2-SAT建图+topsort输出结果
- Select()系统调用及文件描述符集fd_set的应用
- javascript和c++的语法不同之处整理
- C语言的定义与声明
- libpcap中<pcap.h>中定义的函数
- SilkTest入门快打1-录制回放
- 使用Visual Leak Detector检测内存泄漏
- DOM编程之七
- DOM编程之八