zoukankan      html  css  js  c++  java
  • [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
  • 相关阅读:
    Six steps to create google map in the HTML5
    Vocabularies on vegetable, fruit, meat etc.
    常用的Windows命令
    sqlhelper
    素材
    sql sever 跨库查询
    在annotation中却会有ERROR: Duplicate entry
    一份Java学习路线图
    Java算法实例集合(2)
    Java编程规范实践
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/10186730.html
Copyright © 2011-2022 走看看