[POJ3683]Priest John's Busiest Day

link

题目大意

 有$n$个时间安排,可以安排到$2$个时间,问是否可以将时间错开,若能,输出一种方案。

试题分析

 $O(n^2)$暴力判断两者是否能在同一个时间安排,若有两段时间$(u,v)$是不能安排在一起的,则连边$(u,v'),(v,u')$,然后就一个彻彻底底是一个板子了。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
inline int read(){
    int f=1,ans=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    return f*ans;
}
const int N=3996000;
int n;
struct node{
    int u,v,nex;
}x[N<<1];
struct Node{
    int st,end,t;
}k[1001];
int cnt,head[2001];
void add(int u,int v){
//    printf("u:%d v:%d
",u,v);
    x[cnt].u=u,x[cnt].v=v,x[cnt].nex=head[u],head[u]=cnt++;
}
/*上 下+n*/
bool judge(int s1,int e1,int s2,int e2){
    if(s1>s2) swap(s1,s2),swap(e1,e2);
    if(e1>s2) return 0;
    return 1;
}
int dfn[2001],low[2001],num,co[2001],col,sta[2001],tot;
void tarjan(int f){
    dfn[f]=low[f]=++num;
    sta[++tot]=f;
    for(int i=head[f];i!=-1;i=x[i].nex){
        if(!dfn[x[i].v]){
            tarjan(x[i].v);
            low[f]=min(low[f],low[x[i].v]);
        }else if(!co[x[i].v]) low[f]=min(low[f],dfn[x[i].v]);
    }
    if(low[f]==dfn[f]){
        co[f]=++col;
        while(sta[tot]!=f){
            co[sta[tot]]=col;
            tot--;
        }tot--;
    }return;
}
void print(int S){
     printf("%02d:%02d",S/60,S%60);
}
void solve(){
    memset(head,-1,sizeof(head)),cnt=0;memset(co,0,sizeof(co)),col=0,memset(dfn,0,sizeof(dfn)),memset(low,0,sizeof(low)),num=0;
    for(int i=1;i<=n;i++){
        int h1=read(),min1=read(),h2=read(),min2=read(),t=read();
        k[i].st=h1*60+min1,k[i].end=h2*60+min2;
        k[i].t=t;
    }
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            /*i场上 j场上*/
            int s1=k[i].st,e1=k[i].st+k[i].t;int s2=k[j].st,e2=k[j].st+k[j].t;
            if(!judge(s1,e1,s2,e2)) add(i,j+n),add(j,i+n);
            /*i场上 j场下*/
            s1=k[i].st,e1=k[i].st+k[i].t;s2=k[j].end-k[j].t,e2=k[j].end;
            if(!judge(s1,e1,s2,e2)) add(i,j),add(j+n,i+n);
            /*i场下 j场上*/
            s1=k[i].end-k[i].t,e1=k[i].end;s2=k[j].st,e2=k[j].st+k[j].t;
            if(!judge(s1,e1,s2,e2)) add(i+n,j+n),add(j,i);
            /*i场下 j场下*/
            s1=k[i].end-k[i].t,e1=k[i].end;s2=k[j].end-k[j].t,e2=k[j].end;
            if(!judge(s1,e1,s2,e2)) add(i+n,j),add(j+n,i);
        }
    }
    for(int i=1;i<=2*n;i++)
        if(!dfn[i]) tarjan(i);
    for(int i=1;i<=n;i++)
        if(co[i]==co[i+n]){printf("NO
");return;}
    printf("YES
");
    for(int i=1;i<=n;i++){
        if(co[i]<co[i+n]){print(k[i].st);cout<<" ";print(k[i].st+k[i].t);}
        else {print(k[i].end-k[i].t);cout<<" ";print(k[i].end);}
        printf("
");
    }return;
}
int main(){
    while(scanf("%d",&n)!=EOF)solve();
}
View Code
原文地址:https://www.cnblogs.com/si-rui-yang/p/10186730.html