zoukankan      html  css  js  c++  java
  • POJ 3683 Priest John's Busiest Day

    Priest John's Busiest Day

    链接

    题意:

      有n场婚礼,每场婚礼有开始时间和结束时间,每场婚礼都需要牧师的祝福,祝福的时间只能是婚礼开始或者婚礼结束。问能否满足n场婚礼的要求。

    分析:

      2-sat问题。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 2005;
    struct Edge{ int to, nxt; } e[N * N];
    struct Node{ int l, r, d; } A[N];
    int head[N], dfn[N], low[N], sk[N], bel[N], val[N], top, Index, tot, En;
    bool vis[N];
    
    inline void add_edge(int u,int v) {
        ++En; e[En].to = v, e[En].nxt = head[u]; head[u] = En;
    }
    bool judge(int a,int b,int c,int d) {
        return max(a, c) < min(b, d); // 注意此处没有等于号,因为在一个时间结束和开始是可以以的。 
    }
    void tarjan(int u) {
        dfn[u] = low[u] = ++Index;
        sk[++top] = u; vis[u] = 1;
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (!dfn[v]) {
                tarjan(v);
                low[u] = min(low[u], low[v]);
            }
            else if (vis[v]) low[u] = min(low[u], dfn[v]);
        }
        if (low[u] == dfn[u]) {
            ++tot;
            do {
                vis[sk[top]] = 0;
                bel[sk[top]] = tot;
                top --;
            } while (sk[top + 1] != u);
        }
    }
    int main() {
        int n = read();
        char a[10], b[10];
        for (int i = 1; i <= n; ++i) {
            scanf("%s%s%d", a, b, &A[i].d);
            A[i].l = ((a[0] - '0') * 10 + (a[1] - '0')) * 60 + (a[3] - '0') * 10 + (a[4] - '0');
            A[i].r = ((b[0] - '0') * 10 + (b[1] - '0')) * 60 + (b[3] - '0') * 10 + (b[4] - '0');
        }
        for (int i = 1; i <= n; ++i) {
            for (int j = i + 1; j <= n; ++j) {
                if (judge(A[i].l, A[i].l + A[i].d, A[j].l, A[j].l + A[j].d)) {
                    add_edge(i, j + n);
                    add_edge(j, i + n);
                }
                if (judge(A[i].l, A[i].l + A[i].d, A[j].r - A[j].d, A[j].r)) {
                    add_edge(i, j);
                    add_edge(j + n, i + n);
                }
                if (judge(A[i].r - A[i].d, A[i].r, A[j].l, A[j].l + A[j].d)) {
                    add_edge(i + n, j + n);
                    add_edge(j, i);
                }
                if (judge(A[i].r - A[i].d, A[i].r, A[j].r - A[j].d, A[j].r)) {
                    add_edge(i + n, j);
                    add_edge(j + n, i);
                }
            }
        }
        for (int i = 1; i <= n + n; ++i) 
            if (!dfn[i]) tarjan(i);
        for (int i = 1; i <= n; ++i) 
            if (bel[i] == bel[i + n]) { puts("NO"); return 0; }
        puts("YES");
        for (int i = 1; i <= n + n; ++i) {
            int j = i <= n ? i + n : i - n;
            val[i] = bel[i] > bel[j];
        } 
        for (int i = 1; i <= n; ++i) {
            if (!val[i]) printf("%02d:%02d %02d:%02d
    ", A[i].l / 60, A[i].l % 60, (A[i].l + A[i].d) / 60, (A[i].l + A[i].d) % 60);
            else printf("%02d:%02d %02d:%02d
    ", (A[i].r - A[i].d) / 60, (A[i].r - A[i].d) % 60, A[i].r / 60, A[i].r % 60);
        }
        return 0;
    }
  • 相关阅读:
    微服务定义及.Net Core中用的技术
    IPad分屏,当电脑第二显示屏
    .net Core1.0 邮件发送
    AutoMapper总结
    02-C#(基础)基本的定义和说明
    01-.Net编程机制
    C#基础篇--静态成员、抽象成员、接口
    C#基础篇--面向对象(类与对象)
    期末总结
    改动后的封装
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10289858.html
Copyright © 2011-2022 走看看