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\n", 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\n", (A[i].r - A[i].d) / 60, (A[i].r - A[i].d) % 60, A[i].r / 60, A[i].r % 60);
    }
    return 0;
}

 

posted @ 2019-01-18 21:41  MJT12044  阅读(157)  评论(0编辑  收藏  举报