POJ 3683 2-SAT +输出方案
来源:互联网 发布:及时雨淘宝客 编辑:程序博客网 时间:2024/04/28 13:17
输出方案好烦啊 代码超级多~第一次写这种代码,照着别人的代码打的。。
建图:
对于婚礼i和婚礼j,i表示开始主持,i`表示结束主持,j也是一样
枚举每一对不同的i和j,
如果i和j冲突,连接ij`
如果i和j`冲突,连接ij
如果i`和j冲突,连接i`j`
如果i`和j冲突,连接i`j
输出方案:
我们可以把处在同一个强连通分量中的点和边缩成一个点,得到新的有向图G1。然后,我们把G中的所有弧反向,得到图G2。
我们把G中所有顶点置为“未着色”。按照拓扑顺序重复下面的操作:
1、选择第一个未着色的顶点x。把x染成红色。
2、把所有与x矛盾的顶点(如果存在bi,~bi∈B ,且bi属于x代表的强连通分量,~bi属于代表y的强连通分量,那么x和y就是互相矛盾的顶点)及其子孙全部全部染成蓝色。
3、重复操作1和2,直到不存在未着色的点为止。此时,G2中被染成红色的点在图G中对应的顶点集合,就对应着该2-SAT的一组解。
此实现可以递归。
#include<stdio.h>#include<string.h>#include<math.h>#include<stack>#define maxn 2010#define maxe maxn*maxn*3using namespace std;struct node{ int v,next;}edge[maxe];int n;int s[maxn],t[maxn],seq[maxn];int cnt,head1[maxn],head2[maxn],head3[maxn];int scc,idex,dfn[maxn],low[maxn],belong[maxn];int top,sstack[maxn];bool instack[maxn],vis[maxn];int d[maxn],col[maxn];void addedge(int u,int v,int *head){ edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++;}void tarjan(int u){ dfn[u]=low[u]=++idex; sstack[++top]=u; instack[u]=1; for(int i=head1[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(dfn[v]==0) { tarjan(v); low[u]=min(low[v],low[u]); } else if(instack[v]) { low[u]=min(low[u],dfn[v]); } } if(dfn[u]==low[u]) { scc++; while(1) { int tmp=sstack[top--]; addedge(scc,tmp,head3); instack[tmp]=0; belong[tmp]=scc; if(tmp==u) break; } }}void build(){ int i,j; for(i=1;i<=2*n;i++) { for(j=head1[i];j!=-1;j=edge[j].next) { int v=edge[j].v; if(belong[i]!=belong[v]) { addedge(belong[v],belong[i],head2); } } }}bool ok(int i,int j){ if(s[i]>=t[j]||t[i]<=s[j]) return false; return true;}bool check(){ int i; for(i=1;i<=n;i++) { if(belong[i<<1]==belong[i*2-1]) return false; } return true;}void topo(){ int i,j; top=0; stack<int> sta; for(i=1;i<=scc;i++) { for(j=head2[i];j!=-1;j=edge[j].next) { d[edge[j].v]++; } } for(i=1;i<=scc;i++) { if(!d[i]) sta.push(i); } while(!sta.empty()) { int u=sta.top(); sta.pop(); seq[++top]=u; for(i=head2[u];i!=-1;i=edge[i].next) { int v=edge[i].v; d[v]--; if(!d[v]) sta.push(v); } }}void paint(int u){ int k; for(k=head2[u];k!=-1;k=edge[k].next) { if(col[edge[k].v]==0) { col[edge[k].v]=-1; paint(edge[k].v); } }}void color(){ int i,j,k; for(j=1;j<=top;j++) { int u=seq[j]; if(col[u]==0) { col[u]=1; for(i=head3[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(col[belong[((v-1)^1)+1]]==0) { col[belong[((v-1)^1)+1]]=-1; paint(belong[((v-1)^1)+1]); } } } }}void print(){ int i,j; for(i=1;i<=n;i++) { if(col[belong[i*2]]==1) { printf("%02d:%02d %02d:%02d\n",s[i*2]/60,s[i*2]%60,t[i*2]/60,t[i*2]%60); } else { printf("%02d:%02d %02d:%02d\n",s[i*2-1]/60,s[i*2-1]%60,t[i*2-1]/60,t[i*2-1]%60); } }}int main(){ freopen("in.txt","r",stdin); int i,j; scanf("%d",&n); memset(head1,-1,sizeof(head1)); memset(head2,-1,sizeof(head2)); memset(head3,-1,sizeof(head3)); cnt=0; for(i=1;i<=n;i++) { int u,v,tmp; scanf("%d:%d",&u,&v); s[2*i-1]=u*60+v; scanf("%d:%d",&u,&v); t[2*i]=u*60+v; scanf("%d",&tmp); t[2*i-1]=s[2*i-1]+tmp; s[2*i]=t[2*i]-tmp; } for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { if(ok(2*i,2*j)) { addedge(2*i,2*j-1,head1); addedge(2*j,2*i-1,head1); } if(ok(2*i-1,2*j)){addedge(2*i-1,2*j-1,head1);addedge(2*j,2*i,head1);}if(ok(2*i,2*j-1)){addedge(2*i,2*j,head1);addedge(2*j-1,2*i-1,head1);}if(ok(2*i-1,2*j-1)){addedge(2*i-1,2*j,head1);addedge(2*j-1,2*i,head1);} } } scc=0; for(i=1;i<=2*n;i++) { if(!dfn[i]) tarjan(i); } if(!check()) printf("NO\n"); else { printf("YES\n"); build(); topo(); color(); print(); } return 0;}
- POJ 3683 2-SAT +输出方案
- POJ 3683 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 wedding(2-sat 拓扑排序输出方案)
- POJ 3683 Priest John's Busiest Day(2-SAT + 拓扑输出方案)
- POJ 3683 Priest John's Busiest Day(2-SAT输出方案)
- Poj 3683 Priest John's Busiest Day (2-SAT+拓扑排序输出方案)
- poj 3683 2-SAT 拓扑排序输出
- POJ 3683 2-sat 输出解
- UVA 1391 Astronauts(2-SAT + 输出方案)
- gym 100430【2-SAT+输出方案】
- poj 3683 2-sat建图+拓扑排序输出结果
- poj 3683(2-sat+输出一组可行解)
- poj 3683 2-sat问题,输出任意一组可行解
- poj 3683 Priest John's Busiest Day 2-SAT输出
- APNS
- MFC点点滴滴——串口通信
- 关于NandFlash在实际产品使用上的一些经验
- QT VS2008开发环境
- Meshlab中添加external支持库
- POJ 3683 2-SAT +输出方案
- linux命令记录太长看不全怎么办
- 关于硬链接和软连接(符号链接)的区别
- Datagridview数据显示问题查错
- Android开发中常用到方法总结
- 解决Android NDK: Host 'awk' tool is outdated. Please define HOST_AWK to point to Gawk or Nawk !
- pc 连接手机终端,操作手机
- C++深拷贝与浅拷贝的区别联系
- VIM 分屏显示