经典2-sat问题,需要输出解
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn=2e3+9; int head[4][maxn],lon; int dfn[maxn],low[maxn],s[maxn],stack[maxn],instack[maxn]; int que[maxn],in[maxn],to[maxn]; int col[maxn]; int top,con,count,totop; int n,N; struct { int st,ed,last; }data[maxn]; struct { int next,to; }e[maxn*maxn*4]; void edgemake(int from,int to,int head[]) { e[++lon].to=to; e[lon].next=head[from]; head[from]=lon; } void edgeini() { memset(head,-1,sizeof(head)); lon=-1; } int cal(char d[]) { int ret=(d[0]-'0')*600+(d[1]-'0')*60; ret+=(d[3]-'0')*10+(d[4]-'0'); return(ret); } void tarjan(int t) { dfn[t]=low[t]=++count; stack[++top]=t; instack[t]=1; for(int k=head[1][t];k!=-1;k=e[k].next) { int u=e[k].to; if(dfn[u]==-1) { tarjan(u); low[t]=min(low[t],low[u]); } else if(instack[u]==1) low[t]=min(low[t],dfn[u]); } if(dfn[t]==low[t]) { ++con; while(1) { int u=stack[top--]; instack[u]=0; s[u]=con; edgemake(con,u,head[2]); if(u==t) break; } } } void tarjan() { memset(dfn,-1,sizeof(dfn)); count=con=top=0; for(int i=2;i<=n*2+1;i++) if(dfn[i]==-1) tarjan(i); } bool check(int a,int b,int c,int d) { if(c>=b||a>=d) return false; return true; } bool check() { for(int i=2;i<=n*2;i+=2) if(s[i]==s[i+1]) return false; return true; } void makegraph() { for(int i=2;i<=N;i++) for(int k=head[1][i];k!=-1;k=e[k].next) if(s[i]!=s[e[k].to]) edgemake(s[e[k].to],s[i],head[3]); } void topo() { totop=0; int top=0; memset(in,0,sizeof(in)); for(int i=1;i<=con;i++) for(int k=head[3][i];k!=-1;k=e[k].next) in[e[k].to]++; for(int i=1;i<=con;i++) if(in[i]==0) que[++top]=i; while(top) { int u=que[top--]; to[++totop]=u; for(int k=head[3][u];k!=-1;k=e[k].next) { int v=e[k].to; in[v]--; if(in[v]==0) que[++top]=v; } } } void paint(int t) { for(int k=head[3][t];k!=-1;k=e[k].next) { int v=e[k].to; if(col[v]==-1) { col[v]=0; paint(v); } } } void colour() { memset(col,-1,sizeof(col)); for(int i=1;i<=totop;i++) { int u=to[i]; if(col[u]==-1) { col[u]=1; for(int k=head[2][u];k!=-1;k=e[k].next) { int v=e[k].to; if(col[s[v^1]]==-1) { col[s[v^1]]=0; paint(s[v^1]); } } } } } void prin(int t) { if(t%2==0) { printf("%02d:%02d ",data[t/2].st/60,data[t/2].st%60); printf("%02d:%02d\n",(data[t/2].st+data[t/2].last)/60,(data[t/2].st+data[t/2].last)%60); } else { printf("%02d:%02d ",(data[t/2].ed-data[t/2].last)/60,(data[t/2].ed-data[t/2].last)%60); printf("%02d:%02d\n",data[t/2].ed/60,data[t/2].ed%60); } } void prin() { printf("YES\n"); for(int i=2;i<=N;i++) if(col[s[i]]==1) { prin(i); } } int main() { while(scanf("%d",&n)!=EOF) { N=n+n+1; edgeini(); for(int i=1;i<=n;i++) { char st[10],ed[10]; scanf("%s %s %d",st,ed,&data[i].last); data[i].st=cal(st); data[i].ed=cal(ed); } for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) { if(check(data[i].st,data[i].st+data[i].last,data[j].st,data[j].st+data[j].last)) { edgemake(i*2,j*2+1,head[1]); edgemake(j*2,i*2+1,head[1]); } if(check(data[i].st,data[i].st+data[i].last,data[j].ed-data[j].last,data[j].ed)) { edgemake(i*2,j*2,head[1]); edgemake(j*2+1,i*2+1,head[1]); } if(check(data[i].ed-data[i].last,data[i].ed,data[j].st,data[j].st+data[j].last)) { edgemake(i*2+1,j*2+1,head[1]); edgemake(j*2,i*2,head[1]); } if(check(data[i].ed-data[i].last,data[i].ed,data[j].ed-data[j].last,data[j].ed)) { edgemake(i*2+1,j*2,head[1]); edgemake(j*2+1,i*2,head[1]); } } tarjan(); if(!check()) { printf("NO\n"); continue; } makegraph(); topo(); colour(); prin(); } return 0; }