[POJ 3683] Priest John's Busiest Day
[题目链接]
http://poj.org/problem?id=3683
[算法]
2-SAT, 用拓扑排序输出可行解
[代码]
#include <algorithm> #include <bitset> #include <cctype> #include <cerrno> #include <clocale> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <exception> #include <fstream> #include <functional> #include <limits> #include <list> #include <map> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stdexcept> #include <streambuf> #include <string> #include <utility> #include <vector> #include <cwchar> #include <cwctype> #include <stack> #include <limits.h> using namespace std; #define MAXN 1010 #define MAXM 1000010 struct edge { int to,nxt; } e[MAXM << 1],ec[MAXM << 1]; int i,j,n,m,SH,SM,TH,TM,timer,top,cnt,tot,ctot; int S[MAXN],T[MAXN],D[MAXN],low[MAXN << 1],dfn[MAXN << 1],belong[MAXN << 1], stk[MAXN << 1],head[MAXN << 1],chead[MAXN << 1],val[MAXN << 1],opp[MAXN << 1]; bool instack[MAXN << 1]; stack<int> s; inline void addedge(int u,int v) { tot++; e[tot] = (edge){v,head[u]}; head[u] = tot; } inline void addcedge(int u,int v) { ctot++; ec[ctot] = (edge){v,chead[u]}; chead[u] = ctot; } inline bool illegal(int a,int b,int c,int d) { if (a >= c && a < d) return true; if (b > c && b <= d) return true; if (a <= c && b >= d) return true; return false; } inline void tarjan(int u) { int i,v; low[u] = dfn[u] = ++timer; instack[u] = true; s.push(u); for (i = head[u]; i; i = e[i].nxt) { v = e[i].to; if (!dfn[v]) { tarjan(v); low[u] = min(low[u],low[v]); } else if (instack[v]) low[u] = min(low[u],dfn[v]); } if (dfn[u] == low[u]) { cnt++; do { v = s.top(); s.pop(); belong[v] = cnt; instack[v] = false; } while (v != u); } } inline void topsort() { int i,u,v; queue< int > q; static int deg[MAXN << 1]; for (i = 1; i <= cnt; i++) { deg[i] = 0; val[i] = -1; } for (u = 1; u <= 2 * n; u++) { for (i = head[u]; i; i = e[i].nxt) { v = e[i].to; if (belong[u] != belong[v]) { addcedge(belong[v],belong[u]); deg[belong[u]]++; } } } for (i = 1; i <= cnt; i++) { if (!deg[i]) q.push(i); } while (!q.empty()) { u = q.front(); q.pop(); if (val[u] == -1) { val[u] = 0; val[opp[u]] = 1; } for (i = chead[u]; i; i = ec[i].nxt) { v = ec[i].to; if (--deg[v] == 0) q.push(v); } } for (i = 1; i <= n; i++) { if (val[belong[i]] == 0) printf("%02d:%02d %02d:%02d\n",S[i] / 60,S[i] % 60,(S[i] + D[i]) / 60,(S[i] + D[i]) % 60); else printf("%02d:%02d %02d:%02d\n",(T[i] - D[i]) / 60,(T[i] - D[i]) % 60,T[i] / 60,T[i] % 60); } } int main() { scanf("%d",&n); for (i = 1; i <= n; i++) { scanf("%d:%d %d:%d %d",&SH,&SM,&TH,&TM,&D[i]); S[i] = SH * 60 + SM; T[i] = TH * 60 + TM; } for (i = 1; i <= n; i++) { for (j = i + 1; j <= n; j++) { if (illegal(S[i],S[i] + D[i],S[j],S[j] + D[j])) { addedge(i,j + n); addedge(j,i + n); } if (illegal(S[i],S[i] + D[i],T[j] - D[j],T[j])) { addedge(i,j); addedge(j + n,i + n); } if (illegal(T[i] - D[i],T[i],S[j],S[j] + D[j])) { addedge(i + n,j + n); addedge(j,i); } if (illegal(T[i] - D[i],T[i],T[j] - D[j],T[j])) { addedge(i + n,j); addedge(j + n,i); } } } for (i = 1; i <= 2 * n; i++) { if (!dfn[i]) tarjan(i); } for (i = 1; i <= n; i++) { if (belong[i] == belong[i + n]) { printf("NO\n"); return 0; } opp[belong[i]] = belong[i + n]; opp[belong[i + n]] = belong[i]; } printf("YES\n"); topsort(); return 0; }