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;
    }
    
  • 相关阅读:
    Longest Consecutive Sequence 分类: Leetcode(线性表) 2015-02-04 09:54 55人阅读 评论(0) 收藏
    Median of Two Sorted Arrays 分类: Leetcode(线性表) 2015-02-04 09:05 54人阅读 评论(0) 收藏
    Python+Scrapy(完整包全安装过程) 分类: 安装配置说明 2015-02-02 21:29 108人阅读 评论(0) 收藏
    Remove Element 分类: Leetcode(线性表) 2015-01-29 10:47 55人阅读 评论(0) 收藏
    Search in Rotated Sorted Array 分类: Leetcode(线性表) 2015-01-29 10:23 58人阅读 评论(0) 收藏
    机器学习基础(四)LMS,代价函数的求解和概率意义 分类: 机器学习 2015-01-26 14:52 114人阅读 评论(0) 收藏
    机器学习基础(一)线性回归
    AcWing1341. 十三号星期五
    JavaWebServle执行流程解析
    AcWing 466. 回文日期
  • 原文地址:https://www.cnblogs.com/ZGQblogs/p/11600026.html
Copyright © 2011-2022 走看看