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; }