zoukankan      html  css  js  c++  java
  • Priest John's Busiest Day (2-sat)

    题面
    John is the only priest in his town. September 1st is the John's busiest day in a year because there is an old legend in the town that the couple who get married on that day will be forever blessed by the God of Love. This year N couples plan to get married on the blessed day. The i-th couple plan to hold their wedding from time Si to time Ti. According to the traditions in the town, there must be a special ceremony on which the couple stand before the priest and accept blessings. The i-th couple need Di minutes to finish this ceremony. Moreover, this ceremony must be either at the beginning or the ending of the wedding (i.e. it must be either from Si to Si + Di, or from Ti - Di to Ti). Could you tell John how to arrange his schedule so that he can present at every special ceremonies of the weddings.
    题意
    挑战P326
    思路
    (x_i)为第(i)对新人在开始时举行仪式
    (overline{x_i})为第(i)对新人在结束时举行仪式

    如果(x_i)(x_j)冲突,那么(x_i)(x_j)不能同时取到,所以连边(x_i)->(overline{x_j}),(x_j)->(overline{x_i})

    其他三种情况同理

    注意,结束时间可以和另外一个开始时间相同

    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    
    #define fuck(x) cerr<<#x<<" = "<<x<<endl;
    #define debug(a, x) cerr<<#a<<"["<<x<<"] = "<<a[x]<<endl;
    #define lson l,mid,ls
    #define rson mid+1,r,rs
    #define ls (rt<<1)
    #define rs ((rt<<1)|1)
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int loveisblue = 486;
    const int maxn = 1000086;
    const int maxm = 2000086;
    const int inf = 0x3f3f3f3f;
    const ll Inf = 999999999999999999;
    const int mod = 1000000007;
    const double eps = 1e-6;
    const double pi = acos(-1);
    
    
    int n;
    int point1(int x){
        return x;
    }
    int point2(int x){
        return x+n;
    }
    
    char s[10];
    struct node{
        int st,ed,d;
    }a[maxn];
    
    int cal(){
        int tmp1 = (s[0]-48)*10 + s[1]-48;
        int tmp2 = (s[3]-48)*10 + s[4]-48;
        return tmp1*60 + tmp2;
    }
    
    int check(int st1,int st2,int d1,int d2){
        int ed1 = st1+d1;
        int ed2 = st2+d2;
        if(ed1>st2&&ed1<=ed2){
            return true;
        }else return ed2 > st1 && ed2 <= ed1;
    }
    
    int Head[maxn],cnt;
    struct edge{
        int Next,v;
    }e[maxm],et[maxm];
    void add_edge(int u,int v){
    //    cerr<<u<<" "<<v<<endl;
        e[cnt].Next=Head[u];
        e[cnt].v=v;
        Head[u]=cnt++;
    }
    
    int Headt[maxn],cntt;
    void add_edget(int u,int v){
    //    cerr<<u<<" "<<v<<endl;
        et[cntt].Next=Headt[u];
        et[cntt].v=v;
        Headt[u]=cntt++;
    }
    
    int dfn[maxn],low[maxn],color[maxn];
    int Index,sig;//只有这两个变量和dfn需要初始化
    bool vis[maxn];
    stack<int>sta;
    void Tarjan(int u)
    {
        dfn[u]=low[u]=++Index;
        sta.push(u);
        vis[u]=true;
    
        for(int k=Head[u];k!=-1;k=e[k].Next){
            int v = e[k].v;
            if(!dfn[v]){
                Tarjan(v);
                low[u]=min(low[u],low[v]);
            }else if(vis[v]){low[u]=min(low[u],low[v]);}
        }
    
        if(dfn[u]==low[u]){
            sig++;
            while(true){
                int cur=sta.top();
                sta.pop();
                color[cur]=sig;
                vis[cur]=false;
                if(cur==u){break;}
            }
        }
    }
    
    
    queue<int>q;
    int du[maxn];
    int num[maxn];
    void top_sort(){
        int cur = 0;
        while (!q.empty()){
            int tmp = q.front();
    //        fuck(tmp)
            q.pop();
            num[tmp]=++cur;
            for(int k=Headt[tmp];~k;k=et[k].Next){
    //            fuck(k)
                du[et[k].v]--;
                if(du[et[k].v]==0){
                    q.push(et[k].v);
                }
            }
        }
    }
    
    int main() {
        ios::sync_with_stdio(true);
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
        memset(Head,-1,sizeof(Head));
        memset(Headt,-1,sizeof(Headt));
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",s);
            a[i].st = cal();
            scanf("%s",s);
            a[i].ed = cal();
            scanf("%d",&a[i].d);
            for(int j=1;j<i;j++){
                //开始与开始相冲突
                if(check(a[i].st,a[j].st,a[i].d,a[j].d)){
                    add_edge(point1(i),point2(j));
                    add_edge(point1(j),point2(i));
                }if(check(a[i].st,a[j].ed-a[j].d,a[i].d,a[j].d)){
                    add_edge(point1(i),point1(j));
                    add_edge(point2(j),point2(i));
                }if(check(a[i].ed-a[i].d,a[j].st,a[i].d,a[j].d)){
                    add_edge(point1(j),point1(i));
                    add_edge(point2(i),point2(j));
                }if(check(a[i].ed-a[i].d,a[j].ed-a[j].d,a[i].d,a[j].d)){
                    add_edge(point2(i),point1(j));
                    add_edge(point2(j),point1(i));
                }
            }
        }
    
        for(int i=1;i<=n*2;i++){
            if(!dfn[i])Tarjan(i);
        }
    
        bool flag=true;
        for(int i=1;i<=n;i++){
            if(color[point1(i)]==color[point2(i)]){
                flag=false;
            }
        }
        if(flag){
            printf("YES
    ");
            for(int i=1;i<=2*n;i++){
                for(int k=Head[i];~k;k=e[k].Next){
                    if(color[i]!=color[e[k].v]){
                        add_edget(color[i],color[e[k].v]);
                        du[color[e[k].v]]++;
                    }
                }
            }
            for(int i=1;i<=sig;i++){
                if(du[i]==0){
                    q.push(i);
                }
            }
            top_sort();
            for(int i=1;i<=n;i++){
                if(num[color[point1(i)]]>num[color[point2(i)]]){
                    printf("%02d:%02d ",a[i].st/60,a[i].st%60);
                    a[i].st+=a[i].d;
                    printf("%02d:%02d
    ",a[i].st/60,a[i].st%60);
                }else{
                    a[i].ed-=a[i].d;
                    printf("%02d:%02d ",a[i].ed/60,a[i].ed%60);
                    a[i].ed+=a[i].d;
                    printf("%02d:%02d
    ",a[i].ed/60,a[i].ed%60);
                }
            }
        }else{
            printf("NO
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    内存中的堆和栈
    数据库——关系型数据库
    如何创建一个进程,如何进程调用进程
    浅谈C++之冒泡排序、希尔排序、快速排序、插入排序、堆排序、基数排序性能对比分析(好戏在后面,有图有真相)
    Moon.Orm 5.0(MQL版)使用指南
    初学 快速幂 的理解
    2016 杭电
    2015 偶数求和 AC 杭电
    2014 青年歌手大赛 AC
    C语言初学 数组 打印菱形
  • 原文地址:https://www.cnblogs.com/ZGQblogs/p/11600026.html
Copyright © 2011-2022 走看看