D40 2-SAT POJ3683 Priest John's Busiest Day

视频链接:D40 2-SAT POJ3683 Priest John's Busiest Day_哔哩哔哩_bilibili

 

 

 

POJ 3683 -- Priest John's Busiest Day (poj.org)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int N=2005;
int n;
int head[N],to[N*N],ne[N*N],idx;
int dfn[N],low[N],tim,stk[N],top,scc[N],cnt;
int s[N],t[N],d[N];


void add(int a,int b){
  to[++idx]=b,ne[idx]=head[a],head[a]=idx;
}
void tarjan(int x){
  dfn[x]=low[x]=++tim;
  stk[++top]=x;
  for(int i=head[x];i;i=ne[i]){
    int y=to[i];
    if(!dfn[y]){ //若y尚未访问
      tarjan(y);
      low[x]=min(low[x],low[y]);
    }
    else if(!scc[y]) //若y已访问且未处理
      low[x]=min(low[x],dfn[y]);
  }
  
  if(low[x]==dfn[x]){ //若x是SCC的根
    ++cnt;
    for(int y=-1;y!=x;)
      scc[y=stk[top--]]=cnt;
  }
}
int main(){
  scanf("%d",&n);
  for(int i=0;i<n;i++){
    int s0,s1,t0,t1,dd;
    scanf("%d:%d %d:%d %d",&s0,&s1,&t0,&t1,&dd);
    s[i]=s0*60+s1;
    t[i]=t0*60+t1;
    d[i]=dd;
  }
  for(int i=0;i<n;i++)
    for(int j=0;j<i;j++){
      if(s[j]+d[j]>s[i]&&s[i]+d[i]>s[j]) 
        add(i,j+n),add(j,i+n); //i,j重叠
      if(t[j]>s[i]&&s[i]+d[i]>t[j]-d[j]) 
        add(i,j),add(j+n,i+n); //i,j+n重叠
      if(s[j]+d[j]>t[i]-d[i]&&t[i]>s[j]) 
        add(i+n,j+n),add(j,i); //i+n,j重叠
      if(t[j]>t[i]-d[i]&&t[i]>t[j]-d[j]) 
        add(i+n,j),add(j+n,i); //i+n,j+n重叠
    }
  
  for(int i=0;i<n*2;i++) if(!dfn[i])tarjan(i);
  for(int i=0;i<n;i++)
    if(scc[i]==scc[i+n]){puts("NO");return 0;}
  puts("YES");
  for(int i=0;i<n;i++){
    if(scc[i]<scc[i+n]) printf("%02d:%02d %02d:%02d\n",
        s[i]/60,s[i]%60,(s[i]+d[i])/60,(s[i]+d[i])%60);
    else printf("%02d:%02d %02d:%02d\n",
        (t[i]-d[i])/60,(t[i]-d[i])%60,t[i]/60,t[i]%60);
  }
}

 

练习:

Wedding - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 

posted @ 2024-08-07 20:16  董晓  阅读(69)  评论(0编辑  收藏  举报