POJ-3683 Priest John's Busiest Day

图论中的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
", s[i]/60, s[i]%60, (s[i]+d[i])/60, (s[i]+d[i])%60);
		else printf("%02d:%02d %02d:%02d
", (t[i]-d[i])/60, (t[i]-d[i])%60, t[i]/60, t[i]%60);
	return 0;
}

  

原文地址:https://www.cnblogs.com/NanoApe/p/4445338.html