图论中的2-SAT。模板题。
#include <cstdio> #include <cstdlib> #include <algorithm> #include <cctype> #include <cstring> #include <iostream> using namespace std; #define rep(i, l, r) for(int i=l; i<=r; i++) #define travel(x) for(edge *p=fir[x]; p; p=p->n) #define travel2(x) for(edge *p=fir2[x]; p; p=p->n) #define clr(x, c) memset(x, c, sizeof(x)) #define inf 0x7fffffff #define maxn 2009 #define maxm 4345678 int read() { int x=0; char ch=getchar(); while (!isdigit(ch)) ch=getchar(); while (isdigit(ch)) x=x*10+ch-‘0‘, ch=getchar(); return x; } struct edge{int y; edge *n;} e[maxm], *fir[maxn], *fir2[maxn], *pt=e; int n=read(), s[maxn], t[maxn], d[maxn]; int dfn[maxn], low[maxn], q[maxn], b[maxn], scc, now, top, c[maxn], v[maxn], op[maxn]; bool inq[maxn]; inline void Add(int x, int y){pt->y=y, pt->n=fir[x], fir[x]=pt++;} inline void Add2(int x, int y){pt->y=y, pt->n=fir2[x], fir2[x]=pt++, v[y]++;} inline bool can(int a, int b, int c, int d){return(!(b<=c || d<=a));} void tarjan(int x) { dfn[x]=low[x]=++now; q[++top]=x, inq[x]=1; travel(x) if (!dfn[p->y]) tarjan(p->y), low[x]=min(low[x], low[p->y]); else if (inq[p->y]) low[x]=min(low[x], dfn[p->y]); if (low[x]==dfn[x]) { scc++; int a=0; while (a!=x) a=q[top--], inq[a]=0, b[a]=scc; } } void dfs(int x) { if (c[x]) return; else c[x]=-1; travel2(x) dfs(p->y); } int main() { rep(i, 1, n) s[i]=read()*60+read(), t[i]=read()*60+read(), d[i]=read(); rep(i, 1, n) rep(j, 1, n) if (i!=j) { if (can(s[i], s[i]+d[i], s[j], s[j]+d[j])) Add(2*i-1, 2*j), Add(2*j-1, 2*i); if (can(s[i], s[i]+d[i], t[j]-d[j], t[j])) Add(2*i-1, 2*j-1), Add(2*j, 2*i); if (can(t[i]-d[i], t[i], s[j], s[j]+d[j])) Add(2*i, 2*j), Add(2*j-1, 2*i-1); if (can(t[i]-d[i], t[i], t[j]-d[j], t[j])) Add(2*i, 2*j-1), Add(2*j, 2*i-1); } rep(i, 1, 2*n) if (!dfn[i]) tarjan(i); rep(i, 1, n) if (b[i*2-1]==b[i*2]) {puts("NO"); return 0;} puts("YES"); rep(x, 1, 2*n) travel(x) if (b[x]!=b[p->y]) Add2(b[p->y], b[x]); rep(i, 1, n) op[b[2*i-1]]=b[2*i], op[b[2*i]]=b[2*i-1]; rep(i, 1, scc) if(!v[i]) q[++top]=i; while(top) { int now=q[top--]; if (c[now]) continue; c[now]=1; dfs(op[now]); travel2(now) if(--v[p->y]==0) q[++top]=p->y; } rep(i, 1, n) if (c[b[i*2-1]]==1) 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); return 0; }
POJ-3683 Priest John's Busiest Day
时间: 2024-10-19 19:21:25