poj 3683 2-sat问题,输出任意一组可行解
来源:互联网 发布:深圳php培训 编辑:程序博客网 时间:2024/05/03 00:22
/*2sat问题输出任意一组可行解*/#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>#include<queue>#include<vector>using namespace std;#define N 2100struct node {int u,v,next;}ff[N],bian[N*N*8];int head[N],yong,low[N],dfn[N],belong[N],ans,top,index,stac[N],vis[N];void init(){ memset(head,-1,sizeof(head)); yong=index=ans=top=0; memset(vis,0,sizeof(vis)); memset(dfn,0,sizeof(dfn));}void addedge(int u,int v){ bian[yong].u=u;//有的时候不能少,因为下面要用到 bian[yong].v=v; bian[yong].next=head[u]; head[u]=yong++;}void tarjan(int u){ low[u]=dfn[u]=++index; stac[++top]=u; vis[u]=1; int i; for(i=head[u]; i!=-1; i=bian[i].next) { int v=bian[i].v; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(vis[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { ans++; int t; do { t=stac[top--]; belong[t]=ans; vis[t]=0; } while(t!=u); }}int slove(int n){ int i; for(i=0; i<n*2; i++) if(!dfn[i]) tarjan(i); // printf("%d\n",ans); for(i=0; i<n; i++) if(belong[i]==belong[i+n]) return 0; return 1;}int judge(struct node a,struct node b) {if(a.v<=b.u||b.v<=a.u) return 0;return 1;}int fp[N],indegree[N],color[N];vector<int>q[N];void print(struct node a) { printf("%02d:%02d %02d:%02d\n",a.u/60,a.u%60,a.v/60,a.v%60);} void oper(int n) { int i; for(i=0;i<n;i++) { fp[belong[i]]=belong[i+n]; fp[belong[i+n]]=belong[i]; } for(i=1;i<=ans;i++) { q[i].clear(); color[i]=0; indegree[i]=0; } for(i=0;i<yong;i++) { int aa=bian[i].u; int bb=bian[i].v; if(belong[aa]!=belong[bb]) { q[belong[bb]].push_back(belong[aa]); indegree[belong[aa]]++; } } queue<int>qq; for(i=1;i<=ans;i++) { if(indegree[i]==0) qq.push(i); } while(!qq.empty()) { int cur=qq.front(); qq.pop(); if(color[cur]==0) { color[cur]=1; color[fp[cur]]=2; } for(i=0;i<(int)q[cur].size();i++) { int v=q[cur][i]; if(--indegree[v]==0) qq.push(v); } } for(i=0;i<n;i++) { if(color[belong[i]]==1) print(ff[i]); else print(ff[i+n]); } }int main() { int n,i,j,k,u,v,uu,vv,d; while(scanf("%d",&n)!=EOF) { for(i=0;i<n;i++) { scanf("%d:%d %d:%d%d",&u,&v,&uu,&vv,&d); j=u*60+v; k=uu*60+vv; ff[i].u=j;ff[i].v=j+d; ff[i+n].u=k-d;ff[i+n].v=k; } init(); for(i=0;i<n-1;i++) for(j=i+1;j<n;j++) { if(judge(ff[i],ff[j])) { addedge(i,j+n); addedge(j,i+n); } if(judge(ff[i],ff[j+n])) { addedge(i,j); addedge(j+n,i+n); } if(judge(ff[i+n],ff[j])) { addedge(i+n,j+n); addedge(j,i); } if(judge(ff[i+n],ff[j+n])) { addedge(i+n,j); addedge(j+n,i); } } if(!slove(n)) { printf("NO\n"); continue; } printf("YES\n"); oper(n); }return 0;}
0 0
- poj 3683 2-sat问题,输出任意一组可行解
- poj 3683(2-sat+输出一组可行解)
- poj 3648 2-sat 输出任意一组解模板
- Wedding (poj 3648 2-SAT 输出任意一组解)
- 2-sat 输出任意一组可行解&拓扑排序+缩点 poj3683
- poj3648 2-sat <输出任意一组解>
- POJ 3683Priest John's Busiest Day 2-sat输出任意一组解
- loj 1251(2-sat + 输出一组可行解)
- loj 1407(2-sat + 枚举 + 输出一组可行解 )
- POJ 3683 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输出一组解)
- poj 3648 Wedding 【2-sat 经典建图 输出一组可行解 好题】 【tarjan求SCC + 缩点 + 拓扑排序 + 染色】
- POJ 3683 Priest John's Busiest Day (2-SAT+输出可行解)
- [POJ 3683]Priest John's Busiest Day(2-SAT+拓扑排序输出可行解)
- 枚举
- C++中__uuidof是干什么用的
- Manifold Alignment
- How to get access to edit/get pixel values of Mat in OpenCV
- lua杂记
- poj 3683 2-sat问题,输出任意一组可行解
- 打开高通3A算法的日志
- HTTP协议状态码
- 4 sum
- Android launcher3 开发初始篇
- zookeeper的集群安装
- Tripleo之nova-compute 和Ironic的代码深入分析(四)
- Java的一些小点之流程控制与数组
- 【iOS开发-68】APP下载案例:利用tableView自带的cell布局+缓存池cell复用时注意按钮状态的检查