题意:问牧师能否参加每一个婚礼的典礼,典礼只能在婚礼的开始或者结束的时候举行。给出婚礼的时间段,。
在婚礼的开始或者结束,2选1 ,可以用2-sat。
输出婚礼的时间很麻烦,可别人的报告看了好久才勉强看懂。。。。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> using namespace std; const int N = 2009; struct dat{ int tim; } re[N]; int last[N]; struct LT{ int to,nex; } L[N*N]; int F[N],cnt,n; struct E{ int to,nex; } EL[N*N]; int EF[N],Ecnt; void Eadd(int f,int t){ EL[Ecnt].nex = EF[f]; EL[Ecnt].to = t; EF[f] = Ecnt++; } void add(int f,int t){ L[cnt].nex = F[f]; L[cnt].to = t; F[f] = cnt++; } int dfn[N],low[N],col[N],post[N],ind,color; stack<int> S; void tarjan(int k){ low[k] = dfn[k] = ++ind; S.push(k);post[k] = 1; for(int i=F[k];i;i=L[i].nex){ int to = L[i].to; if(!dfn[to]){ tarjan(to); low[k] = min(low[k],low[to]); }else if(post[to]&&dfn[to]<low[k]) low[k] = dfn[to]; } if(low[k]==dfn[k]){ int i;color++; for(i=S.top(),S.pop();i!=k;i=S.top(),S.pop()){ post[i]=0,col[i] = color; Eadd(color,i); } Eadd(color,k); post[k]=0,col[k] = color; } } bool xx(int a1,int b1,int a2,int b2){ if(a2>=a1&&a2<a1+b1) return true; if(a1>=a2&&a1<a2+b2) return true; return false; } int ans[N]; int main() { freopen("in.txt","r",stdin); while(~scanf("%d",&n)){ int hh,mm; for(int i=0;i<n;i++){ scanf("%d:%d",&hh,&mm); re[i].tim=hh*60+mm; scanf("%d:%d",&hh,&mm); scanf("%d",&last[i]); last[i+n]=last[i]; re[i+n].tim=hh*60+mm-last[i]; } memset(F,0,sizeof(F));cnt=1; memset(EF,0,sizeof(EF));Ecnt = 1; for(int i=0;i<(n<<1);i++){ for(int j=i+1;j<(n<<1);j++){ if(i==j) continue; if(xx(re[i].tim,last[i],re[j].tim,last[j])) { int k=(i+n)%(n*2),l=(j+n)%(n*2); add(i,l); add(j,k); } } } memset(dfn,0,sizeof(dfn)); memset(col,0,sizeof(col)); color=0;ind=1; for(int i=0;i<(n<<1);i++) if(!dfn[i]) tarjan(i); bool fin= false; for(int i=0;i<n;i++) if(col[i]==col[i+n])fin = true; if(fin){ printf("NO\n"); }else{ printf("YES\n"); memset(ans,-1,sizeof(ans)); for(int i=1;i<=color;i++) if(ans[i]==-1){ ans[i]=1; for(int j=EF[i];j;j=EL[j].nex){ int to = EL[j].to; ans[col[(to+n)%(n<<1)]] = 0; } } for(int i=0;i<n;i++){ if(ans[col[i]]==1){ int t1=re[i].tim,t2=re[i].tim+last[i]; printf("%02d:%02d %02d:%02d\n",t1/60,t1%60,t2/60,t2%60); }else{ int t1=re[i+n].tim,t2=re[i+n].tim+last[i]; printf("%02d:%02d %02d:%02d\n",t1/60,t1%60,t2/60,t2%60); } } } } return 0; }