• POJ3683Priest John's Busiest Day(2sat)


    POJ 2-sat六题之三

    http://blog.sina.com.cn/s/blog_64675f540100k1cd.html

    题目描述:有n个婚礼,每个婚礼有起始时间si,结束时间ti,还有一个主持时间ti,ti必须安排在婚礼的开始或者结束,主持由祭祀来做,但是只有一个祭祀,所以各个婚礼的主持时间不能重复,问你有没有可能正常的安排主持时间,不能输出no,能的话要输出具体的答案:即每个婚礼的主持时间段是什么样的。

    解题报告:

    对于每个婚礼,主持时间只有两种状态,而且各个婚礼之间的主持时间之间有相互限制,所以想到2-sat。

    构图:

    对于婚礼i和婚礼j。i表示在开始主持,i2表示在结束主持,j类似。

    枚举每一对不同的i和j。

    如果i和j冲突。连接i j2

    如果i和j2冲突,连接i j

    如果i2和j冲突,连接i2 j2

    如果i2和j2冲突,连接i2 j

    // File Name: 3683.cpp
    // Author: zlbing
    // Created Time: 2013/1/30 13:43:55
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    using namespace std;
    #define MAXN 1050
    
    int T[MAXN][3];
    struct TwoSAT{
        int n;
        vector<int>G[MAXN*2];
        bool mark[MAXN*2];
        stack<int>S;
        bool dfs(int x)
        {
            if(mark[x^1])return false;
            if(mark[x])return true;
            mark[x]=true;
            S.push(x);
            for(int i=0;i<G[x].size();i++)
            {
                int v=G[x][i];
                if(!dfs(v))return false;
            }
            return true;
        }
        void init(int _n)
        {
            n=_n;
            for(int i=0;i<2*n;i++)
                G[i].clear();
            memset(mark,0,sizeof(mark));
        }
    /*    void add_clause(int x,int xval,int y,int yval)
        {
            x=x*2+xval;
            y=y*2+yval;
            G[x^1].push_back(y);
            G[y^1].push_back(x);
        }
    */
        void add_clause(int x,int y)
        {
            G[x].push_back(y);
        }
        bool solve()
        {
            for(int i=0;i<2*n;i=i+2)
            {
                if(!mark[i]&&!mark[i+1]){
                      while(!S.empty())
                      {
                          S.pop();
                      }
                    if(!dfs(i))
                    {
                        while(!S.empty())
                        {
                            mark[S.top()]=false;
                            S.pop();
                        }
                        if(!dfs(i+1))return false;
                    }
                }
            }
            printf("YES\n");
            int e;
            for(int i=0;i<2*n;i++)
                if(mark[i]){
                    int j=T[i/2][i%2];
                    if(i%2)e=-T[i/2][2];
                    else e=T[i/2][2];
                    if(i&1)
                    printf("%02d:%02d %02d:%02d\n",(j+e)/60,(j+e)%60,j/60,j%60);
                    else 
                    printf("%02d:%02d %02d:%02d\n",j/60,j%60,(j+e)/60,(j+e)%60);
                }
            return true;
        }
    };
    TwoSAT solver;
    int main(){
        int n;
        while(~scanf("%d",&n))
        {
            solver.init(n);
            for(int i=0;i<n;i++)
            {
                int a,b;
                scanf("%d:%d",&a,&b);
                a=a*60+b;
                int c,d;
                scanf("%d:%d",&c,&d);
                c=c*60+d;
                int e;
                scanf("%d",&e);
                T[i][0]=a,T[i][1]=c,T[i][2]=e;
            }
            for(int i=0;i<n;i++)
                for(int j=i+1;j<n;j++)
                {
                    if(i==j)continue;
                    if(T[j][0]+T[j][2]>T[i][0]&&T[i][0]+T[i][2]>T[j][0])
                             solver.add_clause(i*2,2*j+1);
                    if(T[j][1]>T[i][0]&&T[i][0]+T[i][2]>T[j][1]-T[j][2])
                        solver.add_clause(i*2,2*j);
                    if(T[j][0]+T[j][2]>T[i][1]-T[i][2]&&T[i][1]>T[j][0])
                        solver.add_clause(i*2+1,2*j+1);
                    if(T[j][1]>T[i][1]-T[i][2]&&T[i][1]>T[j][1]-T[j][2])
                        solver.add_clause(i*2+1,2*j);
                }
            if(!solver.solve())
                printf("NO\n");
        }
        return 0;
    }
  • 相关阅读:
    mui 卡片视图 遮罩蒙版
    mui 滑块开关 进度条 以及如何获取值
    mui 普通新闻文字列表 图文新闻列表
    HDU4553 约会安排
    HDU4614 Vases and Flowers
    HDU 1540 Tunnel Warfare 线段树区间合并
    Codeforces Round #359 (Div. 1)
    POJ3264 Balanced Lineup 线段树区间最大值 最小值
    1351 topcoder 吃点心
    POJ 3321 Apple Tree(dfs序树状数组)
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2883829.html
Copyright © 2020-2023  润新知