终于找到一道要输出方案的题,虽然还是比较裸的题QAQ。
建边分别处理四种情况。。具体见代码。
然后我们tarjan缩环后连反边跑拓扑排序就好啦,从一个点开始,如果没有被标记,就打上“选择”的记号,然后沿着反边出发打上“不选”的记号。最后统计答案就好啦。
开始直接没调用tarjan()。。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[10];
int n,cnt,top,tot,scc;
int s1[1005],s2[1005],t1[1005],t2[1005];
int op[2005],dfn[2005],low[2005],q[2005],head[2005],head_[2005],ind[2005],color[2005],stack[2005],belong[2005];
int list[2000005],next[2000005],list_[2000005],next_[2000005];
bool inset[2005];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void insert(int x,int y)
{
next[++cnt]=head[x];
head[x]=cnt;
list[cnt]=y;
}
inline void insert_(int x,int y)
{
next_[++cnt]=head_[x];
head_[x]=cnt;
list_[cnt]=y;
ind[y]++;
}
inline bool judge(int a,int b,int c,int d)
{
return b<=c||d<=a;
}
void dfs(int x)
{
low[x]=dfn[x]=++tot;
stack[++top]=x;
inset[x]=1;
for (int i=head[x];i;i=next[i])
if (!dfn[list[i]])
{
dfs(list[i]);
low[x]=min(low[x],low[list[i]]);
}
else if (inset[list[i]]) low[x]=min(low[x],dfn[list[i]]);
if (low[x]==dfn[x])
{
int i=-1; scc++;
while (i!=x)
{
i=stack[top--];
belong[i]=scc;
inset[i]=0;
}
}
}
inline void tarjan()
{
for (int i=1;i<=2*n;i++) if (!dfn[i]) dfs(i);
}
inline void rebuild()
{
cnt=0;
for (int x=1;x<=2*n;x++)
for (int i=head[x];i;i=next[i])
if (belong[x]!=belong[list[i]])
insert_(belong[list[i]],belong[x]);
}
void col(int x)
{
if (color[x]) return;
color[x]=-1;
for (int i=head_[x];i;i=next_[i]) col(list_[i]);
}
inline void topo_sort()
{
int t=0,w=0;
for (int i=1;i<=scc;i++)
if (!ind[i]) q[++w]=i;
while (t<w)
{
int x=q[++t];
if (color[x]) continue;
color[x]=1; col(op[x]);
for (int i=head_[x];i;i=next_[i])
{
ind[list_[i]]--;
if (!ind[list_[i]]) q[++w]=list_[i];
}
}
}
inline void print(int x)
{
printf("%.2d:",x/60);
printf("%.2d ",x%60);
}
int main()
{
n=read();
for (int i=1;i<=n;i++)
{
scanf("%s",s);
int x1,x2,delta;
x1=(s[0]-'0')*10+(s[1]-'0');
x2=(s[3]-'0')*10+(s[4]-'0');
s1[i]=x1*60+x2;
scanf("%s",s);
x1=(s[0]-'0')*10+(s[1]-'0');
x2=(s[3]-'0')*10+(s[4]-'0');
t2[i]=x1*60+x2;
delta=read();
t1[i]=s1[i]+delta; s2[i]=t2[i]-delta;
}
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
{
if (!judge(s1[i],t1[i],s1[j],t1[j]))
insert(2*i-1,2*j),insert(2*j-1,2*i);
if (!judge(s1[i],t1[i],s2[j],t2[j]))
insert(2*i-1,2*j-1),insert(2*j,2*i);
if (!judge(s2[i],t2[i],s1[j],t1[j]))
insert(2*i,2*j),insert(2*j-1,2*i-1);
if (!judge(s2[i],t2[i],s2[j],t2[j]))
insert(2*i,2*j-1),insert(2*j,2*i-1);
}
tarjan();
for (int i=1;i<=n;i++)
if (belong[2*i-1]==belong[2*i]) {puts("NO"); return 0;}
puts("YES");
rebuild();
for (int i=1;i<=n;i++)
{
op[belong[2*i]]=belong[2*i-1];
op[belong[2*i-1]]=belong[2*i];
}
topo_sort();
for (int i=1;i<=n;i++)
if (color[belong[2*i-1]]==1)
print(s1[i]),print(t1[i]),puts("");
else print(s2[i]),print(t2[i]),puts("");
return 0;
}