POJ 3683 Priest John's Busiest Day[2-SAT 构造解]
题意:
$n$对$couple$举行仪式,有两个时间段可以选择,问是否可以不冲突举行完,并求方案
两个时间段选择对应一真一假,对于有时间段冲突冲突的两人按照$2-SAT$的规则连边(把不冲突的时间段连起来)
然后本题需要构造解,所以要$SCC$缩点反向建图记录否定再拓扑排序$dfs$染色,好麻烦...
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int N=2005,M=1e6+5; typedef long long ll; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int n,m; struct person{ int a,b; }p[N]; struct edge{ int v,ne; }e[M],e2[M]; int h[N],h2[N],cnt=0; inline void ins(int u,int v){ cnt++; e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt; } inline void ins2(int u,int v){ cnt++; e2[cnt].v=v;e2[cnt].ne=h2[u];h2[u]=cnt; } inline bool isIn(int x,int y){ if(p[x].b<=p[y].a||p[x].a>=p[y].b) return false; return true; } void buildGraph(){ for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++){ int x=i<<1,y=j<<1; if(isIn(x-1,y-1)) ins(x-1,y),ins(y-1,x); if(isIn(x-1,y)) ins(x-1,y-1),ins(y,x); if(isIn(x,y-1)) ins(x,y),ins(y-1,x-1); if(isIn(x,y)) ins(x,y-1),ins(y,x-1); } } int dfn[N],low[N],dfc,belong[N],scc; int st[N],top; void dfs(int u){ dfn[u]=low[u]=++dfc; st[++top]=u; for(int i=h[u];i;i=e[i].ne){ int v=e[i].v; if(!dfn[v]){ dfs(v); low[u]=min(low[u],low[v]); }else if(!belong[v]) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]){ scc++; while(true){ int x=st[top--]; belong[x]=scc; if(x==u) break; } } } bool judge(){ for(int i=1;i<=n;i++) if(belong[i<<1]==belong[(i<<1)-1]) return false; return true; } int ind[N]; void rebuildGraph(){ int _=n<<1; cnt=0; for(int u=1;u<=_;u++) for(int i=h[u];i;i=e[i].ne) if(belong[u]!=belong[e[i].v]) ins2(belong[e[i].v],belong[u]),ind[belong[u]]++; } int color[N]; void dfsCol(int u){ if(color[u]) return; color[u]=2; for(int i=h2[u];i;i=e2[i].ne) dfsCol(e2[i].v); } int opp[N]; void topoSort(){ top=0; for(int i=1;i<=scc;i++) if(!ind[i]) st[++top]=i; while(top){ int u=st[top--]; if(color[u]) continue; color[u]=1;dfsCol(opp[u]); for(int i=h2[u];i;i=e2[i].ne){ int v=e2[i].v; ind[v]--; if(!ind[v]) st[++top]=v; } } } void print(int a,int b){ printf("%.2d:%.2d ",a/60,a%60); printf("%.2d:%.2d ",b/60,b%60); puts(""); } int main(){ freopen("in","r",stdin); n=read(); for(int i=1;i<=n;i++){ int x=i<<1,t; t=read(); p[x-1].a=t*60+read(); t=read(); p[x].b=t*60+read(); t=read(); p[x-1].b=p[x-1].a+t; p[x].a=p[x].b-t; } buildGraph(); int _=n<<1; for(int i=1;i<=_;i++) if(!dfn[i]) dfs(i); if(!judge()) puts("NO"); else{ puts("YES"); rebuildGraph(); for(int i=1;i<=n;i++){ int x=i<<1; opp[belong[x]]=belong[x-1]; opp[belong[x-1]]=belong[x]; } topoSort(); for(int i=1;i<=n;i++){ int x=i<<1; if(color[belong[x]]==1) print(p[x].a,p[x].b); else print(p[x-1].a,p[x-1].b); } } }
Copyright:http://www.cnblogs.com/candy99/