• POJ 3683 Priest John's Busiest Day


    这里写图片描述

    看这个题目之前可以先看POJ2186复习一下强联通分量的分解

    题意:给出N个开始时间和结束时间和持续时间三元组,持续时间可以在开始后或者结束前,问如何分配可以没有冲突。

    —————–我是分割线———————————

    先解释一下合取范式(离散数学已经学过):
    如果合取范式中的每个字句的文字个数不超过两个就称为2-SAT问题
    一般性称为n-SAT问题

    举个栗子:(ab)¬a 在a为false而b为true时整个范式的取值为真。

    利用强连通分量的知识,就可以在布尔公式字句个数的线性时间内解决2-SAT问题。在离散数学中我们已经学过蕴含范式。对于ab可以转换为¬ab)(¬ba)

    下面就是建图过程了:
    对于每一个布尔变量x,构造两个顶点x和¬x;以为有向边建立有向图。
    在有向图中,如果a能到达b的话,a为真则b也为真。
    因此在同一个强连通分量中所含的所有文字代表的布尔值都相同。
    特别注意的是,假设x和都在同一个强连通分量中,则显然,这个强连通分量始终不可能为真。
    相反,如果不存在这样的布尔变量,对于每个布尔变量x,让

    x所在的强连通分量的拓扑序在¬x所在的强连通分量之后,(也就是比较二者的拓扑序)

    就是使得该公式的值为真的一组合适的布尔变量的解。

    ——————-我是分割线————————-

    对于每个三元组,只有在开始之后和结束之前两种选择,不妨设变量xi
    xi为真<->在开始之后开始插入时间长度

    有了这些理论支持,对于每个三元组,无非有四种组合情况:
    开始-开始
    开始和结束
    结束-开始
    结束-结束
    (本题中样例中没有结束-开始)
    如果开始-开始冲突,那么¬x1¬x2的值为真。
    所以合取范式为:(¬x1¬x2)(¬x1x2)(x1x2)
    当x1的值为真x2的值为假时,其值为真。
    接下来就是进行强连通分量分解并判断是否有使得布尔公式的值为真的一组布尔变量赋值。
    (这里利用带了前面的那个定理:如果x所在的强连通分量的拓扑序在¬xx

    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <functional>
    #include <set>
    #include <cmath>
    using namespace std;
    #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
    #define pb push_back
    #define PB pop_back
    #define bk back()
    #define fs first
    #define se second
    #define sq(x) (x)*(x)
    #define eps (3e-7)
    #define IINF (1<<29)
    #define LINF (1ll<<59)
    #define INF (1000000000)
    #define FINF (1e3)
    #define clr(x) memset((x),0,sizeof (x));
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    typedef pair<int,int> P;
    
    const int maxn=2005;
    int n;
    int a[maxn][3];
    char r[300];
    vector<int> G[maxn],rG[maxn],od;
    bool vis[maxn];
    int sccid[maxn];
    int get(char a,char b){
        return (a-'0')*10+b-'0';
    }
    bool inter(int a,int b,int c,int d){
        return !(a>=d||b<=c);
    }
    void addedge(int a,int b){
        G[a].pb(b);
        rG[b].pb(a);
    }
    void dfs1(int v){
        vis[v]=1;
        for(int i=0;i<G[v].size();i++){
            int u=G[v][i];
            if(!vis[u]) dfs1(u);
        }
        od.pb(v);
    }
    void dfs2(int v,int k){
        vis[v]=1;
        sccid[v]=k;
        for(int i=0;i<rG[v].size();i++){
            int u=rG[v][i];
            if(!vis[u]) dfs2(u,k);
        }
    }
    int V;
    void scc(){
        clr(vis);od.clear();
        for(int i=1;i<=V;i++){
            if(!vis[i]) dfs1(i);
        }
        clr(vis);
        int id=1;
        for(int i=od.size()-1;i>=0;i--){
            int v=od[i];
            if(!vis[v]) dfs2(v,id++);
        }
    }
    void build(){
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                if(inter(a[i][0],a[i][0]+a[i][2],a[j][0],a[j][0]+a[j][2])){
                    addedge(i,j+n);
                    addedge(j,i+n);
                }
                if(inter(a[i][0],a[i][0]+a[i][2],a[j][1]-a[j][2],a[j][1])){
                    addedge(i,j);
                    addedge(j+n,i+n);
                }
                if(inter(a[i][1]-a[i][2],a[i][1],a[j][0],a[j][0]+a[j][2])){
                    addedge(i+n,j+n);
                    addedge(j,i);
                }
                if(inter(a[i][1]-a[i][2],a[i][1],a[j][1]-a[j][2],a[j][1])){
                    addedge(i+n,j);
                    addedge(j+n,i);
                }
            }
        }
    }
    bool ans[maxn];
    int main(){
        freopen("/home/slyfc/CppFiles/in","r",stdin);
        //freopen("defense.in","r",stdin);
        //freopen("defense.out","w",stdout);
        cin>>n;
        V=n*2;
        for(int i=1;i<=n;i++){
            scanf("%s",r);
            a[i][0]=get(r[0],r[1])*60+get(r[3],r[4]);
            scanf("%s",r);
            a[i][1]=get(r[0],r[1])*60+get(r[3],r[4]);
            scanf("%d",&a[i][2]);
        }
        build();
        scc();
        for(int i=1;i<=n;i++){
            if(sccid[i]==sccid[i+n]){
                puts("NO");
                return 0;
            }else{
                if(sccid[i]>sccid[i+n]){
                    ans[i]=1;
                }else{
                    ans[i]=0;
                }
            }
        }
        puts("YES");
        for(int i=1;i<=n;i++){
            if(ans[i]){
                int s=a[i][0],t=a[i][0]+a[i][2];
                printf("%02d:%02d %02d:%02d
    ",s/60,s%60,t/60,t%60);
            }else{
                int s=a[i][1]-a[i][2],t=a[i][1];
                printf("%02d:%02d %02d:%02d
    ",s/60,s%60,t/60,t%60);
            }
        }
        return 0;
    }
  • 相关阅读:
    常用head标签
    php自定义配置文件简单写法
    sublimeText常用插件
    addslashes,htmlspecialchars,htmlentities转换或者转义php特殊字符防止xss攻击以及sql注入
    服务器安装node全教程
    Sublime Text 3 Build 3176 License
    [转]Zend Studio 文件头和方法注释设置
    给php代码添加规范的注释phpDocumentor
    [转]php 在各种web服务器的运行模式
    .htaccess文件url重写小记
  • 原文地址:https://www.cnblogs.com/bryce1010/p/9386906.html
Copyright © 2020-2023  润新知