题目链接
http://poj.org/problem?id=3683
题目大意
思路
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXE 4100000
#define MAXV 2100
using namespace std;
struct edge
{
int u,v,next;
}edges1[MAXE],edges2[MAXE];
int head1[MAXV],nCount1=0;
int head2[MAXV],nCount2=0;
int inDegree[MAXV];
void AddEdge1(int U,int V)
{
edges1[++nCount1].u=U;
edges1[nCount1].v=V;
edges1[nCount1].next=head1[U];
head1[U]=nCount1;
}
void AddEdge2(int U,int V)
{
inDegree[V]++;
edges2[++nCount2].u=U;
edges2[nCount2].v=V;
edges2[nCount2].next=head2[U];
head2[U]=nCount2;
}
void add(int a,int typea,int b,int typeb)
{
AddEdge1((a<<1)+typea,((b<<1)+typeb)^1);
AddEdge1(((a<<1)+typea)^1,(b<<1)+typeb);
}
int dfn[MAXV],low[MAXV],dfs_time=0;
int stack[MAXV<<1],top=0;
bool inStack[MAXV];
int belong[MAXV],scc_cnt=0;
int opp[MAXV]; //opp[i]=与点i相矛盾的点
void TarjanSCC(int u)
{
dfn[u]=low[u]=++dfs_time;
stack[++top]=u;
inStack[u]=true;
for(int p=head1[u];p!=-1;p=edges1[p].next)
{
int v=edges1[p].v;
if(!dfn[v])
{
TarjanSCC(v);
low[u]=min(low[u],low[v]);
}
else if(inStack[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
scc_cnt++;
while(1)
{
int now=stack[top];
inStack[now]=false;
top--;
belong[now]=scc_cnt;
if(now==u) break;
}
}
}
int n;
int starttime[MAXV],endtime[MAXV]; //每场婚礼的开始时间与结束时间
int col[MAXV]; //col[i]=点i的颜色
int q[MAXV<<1]; //拓扑排序时用的队列
void TopoSort() //拓扑排序
{
memset(col,0,sizeof(col));
int h=0,t=0;
for(int i=1;i<=scc_cnt;i++) if(!inDegree[i]) q[t++]=i;
while(h<t)
{
int u=q[h++];
if(!col[u]) //u未着色
{
col[u]=1;
col[opp[u]]=-1;
}
for(int p=head2[u];p!=-1;p=edges2[p].next)
{
int v=edges2[p].v;
inDegree[v]--;
if(!inDegree[v])
q[t++]=v;
}
}
//下面是选取颜色1的来输出
for(int i=1;i<=n;i++)
{
if(col[belong[i*2]]==-1)
{
int sthour=starttime[2*i]/60;
int stmin=starttime[2*i]%60;
int edhour=endtime[2*i]/60;
int edmin=endtime[2*i]%60;
printf("%02d:%02d %02d:%02d\n",sthour,stmin,edhour,edmin);
}
else
{
int sthour=starttime[2*i+1]/60;
int stmin=starttime[2*i+1]%60;
int edhour=endtime[2*i+1]/60;
int edmin=endtime[2*i+1]%60;
printf("%02d:%02d %02d:%02d\n",sthour,stmin,edhour,edmin);
}
}
}
bool hasIntersec(int i,int j) //看i和j两个时间段是否相冲突,冲突返回true
{
if(starttime[i]>=endtime[j]||endtime[i]<=starttime[j]) return false;
return true;
}
int main()
{
memset(head1,-1,sizeof(head1));
memset(head2,-1,sizeof(head2));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int hour1,min1,hour2,min2,t;
scanf("%d:%d %d:%d %d",&hour1,&min1,&hour2,&min2,&t);
starttime[i*2]=hour1*60+min1;
endtime[i*2]=hour1*60+min1+t;
starttime[i*2+1]=hour2*60+min2-t;
endtime[i*2+1]=hour2*60+min2;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j) continue;
if(hasIntersec(i*2,j*2)) AddEdge1(i*2,j*2+1);
if(hasIntersec(i*2,j*2+1)) AddEdge1(i*2,j*2);
if(hasIntersec(i*2+1,j*2)) AddEdge1(i*2+1,j*2+1);
if(hasIntersec(i*2+1,j*2+1)) AddEdge1(i*2+1,j*2);
/*if(hasIntersec(i*2,j*2)) add(i,0,j,0);
if(hasIntersec(i*2,j*2+1)) add(i,0,j,1);
if(hasIntersec(i*2+1,j*2)) add(i,1,j,0);
if(hasIntersec(i*2+1,j*2+1)) add(i,1,j,1);*/
}
for(int i=2;i<=2*n+1;i++)
if(!dfn[i])
TarjanSCC(i);
bool flag=true;
for(int i=1;i<=n;i++)
{
if(belong[i*2]==belong[i*2+1])
{
flag=false;
break;
}
opp[belong[i*2]]=belong[i*2+1];
opp[belong[i*2+1]]=belong[i*2];
}
if(flag) puts("YES");
else
{
puts("NO");
return 0;
}
for(int i=1;i<=nCount1;i++)
{
int u=edges1[i].u,v=edges1[i].v;
if(belong[u]!=belong[v])
AddEdge2(belong[u],belong[v]);
}
TopoSort();
return 0;
}