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;
    }
    
  • 相关阅读:
    Windows快捷键大全
    Reducing browser privileges
    文献搜索方法大全
    知道不知道
    在IE浏览器中使用Windows窗体控件
    Vs.net 2005 自带的Performance Tools (转贴)
    Internet Explorer Developer Toolbar(工具)插件
    编写高性能 Web 应用程序的 10 个技巧
    c# 读取Access数据库资料
    用DataReader读取数据
  • 原文地址:https://www.cnblogs.com/ZGQblogs/p/11600026.html
Copyright © 2011-2022 走看看