POJ 3683 2-SAT 输出方案
| Time Limit: 2000MS | Memory Limit: 65536K | |||
| Total Submissions: 7216 | Accepted: 2464 | Special Judge | ||
Description
John is the only priest in his town. September 1st is the John's busiest day
in a year because there is an old legend in the town that the couple who get
married on that day will be forever blessed by the God of Love. This year
N couples plan to get married on the blessed day. The i-th couple
plan to hold their wedding from time Si to time
Ti. According to the traditions in the town, there must be a
special ceremony on which the couple stand before the priest and accept
blessings. The i-th couple need Di minutes to finish
this ceremony. Moreover, this ceremony must be either at the beginning or the
ending of the wedding (i.e. it must be either from Si to
Si + Di, or from Ti -
Di to Ti). Could you tell John how to
arrange his schedule so that he can present at every special ceremonies of the
weddings.
Note that John can not be present at two weddings
simultaneously.
Input
The first line contains a integer N ( 1 ≤ N ≤ 1000).
The
next N lines contain the Si, Ti and
Di. Si and Ti are in the
format of hh:mm.
Output
The first line of output contains "YES" or "NO" indicating whether John can
be present at every special ceremony. If it is "YES", output another N
lines describing the staring time and finishing time of all the
ceremonies.
Sample Input
2 08:00 09:00 30 08:15 09:00 20
Sample Output
YES 08:00 08:30 08:40 09:00
题意:很简单,不解释。
思路:首先根据冲突关系建立图,tarjin缩点,判断是否可行,假如不可行,直接跳出,否则根据缩点重新建逆图,拓扑排序染色,然后输出方案。
代码:
#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<queue>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
#include<math.h>
using namespace std;
const int maxn=5000;
int head[maxn],head1[maxn],tol,tot,Stack[maxn],top,indexx,scc,instack[maxn],belong[maxn],cf[maxn],col[maxn],in[maxn],n,low[maxn],dfn[maxn];
struct node
{
int next,to;
}edge[maxn*100],edge1[100*maxn];
void add(int u,int v)
{
edge[tol].to=v;
edge[tol].next=head[u];
head[u]=tol++;
}
void add1(int u,int v)
{
edge1[tot].to=v;
edge1[tot].next=head1[u];
head1[u]=tot++;
}
struct Node
{
int st,ed;
}pp[maxn];
bool ins(Node a,Node b)
{
if(a.st>=b.st&&a.st<b.ed)return 1;
if(b.st>=a.st&&b.st<a.ed)return 1;
return 0;
}
void tarjin(int u)
{
low[u]=dfn[u]=++indexx;
Stack[top++]=u;instack[u]=1;
int i,v;
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(!dfn[v])
{
tarjin(v);
if(low[u]>low[v])low[u]=low[v];
}
else if(instack[v]&&low[u]>dfn[v])low[u]=dfn[v];
}
if(low[u]==dfn[u])
{
scc++;
do
{
v=Stack[--top];
instack[v]=0;
belong[v]=scc;
}while(u!=v);
}
}
void solve()
{
memset(head,-1,sizeof(head));tol=0;
int i,j,u,v;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
{
if(ins(pp[2*i],pp[2*j]))
{
add(2*i,2*j+1);
add(2*j,2*i+1);
}
if(ins(pp[2*i],pp[2*j+1]))
{
add(2*i,2*j);
add(2*j+1,2*i+1);
}
if(ins(pp[2*i+1],pp[2*j]))
{
add(2*i+1,2*j+1);
add(2*j,2*i);
}
if(ins(pp[2*i+1],pp[2*j+1]))
{
add(2*i+1,2*j);
add(2*j+1,2*i);
}
}
// cout<<tol<<endl;
memset(dfn,0,sizeof(dfn));
memset(belong,0,sizeof(belong));
memset(instack,0,sizeof(instack));
indexx=scc=top=0;
for(i=0;i<2*n;i++)if(!dfn[i])tarjin(i);
int flag=1;
memset(cf,0,sizeof(cf));
memset(head1,-1,sizeof(head));tot=0;
memset(in,0,sizeof(in));
memset(col,0,sizeof(col));
for(i=0;i<n;i++)
{
if(belong[2*i]==belong[2*i+1])
{
flag=0;break;
}
cf[belong[2*i]]=belong[2*i+1];
cf[belong[2*i+1]]=belong[2*i];
}
if(flag==0)
{
puts("NO");return;
}
puts("YES");
for(u=0;u<2*n;u++)
{
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(belong[u]!=belong[v])
{
in[belong[u]]++;
add1(belong[v],belong[u]);
}
}
}
queue<int> que;
for(i=1;i<=scc;i++)if(in[i]==0)que.push(i);
while(!que.empty())
{
int cur=que.front();que.pop();
if(col[cur]==0)
{
col[cur]=1;
col[cf[cur]]=-1;
}
for(i=head1[cur];i!=-1;i=edge1[i].next)
{
v=edge1[i].to;
if(--in[v]==0)que.push(v);
}
}
int a,b,c,d;
for(i=0;i<n;i++)
{
if(col[ belong[2*i] ]==1)
{
a=pp[2*i].st/60;
b=pp[2*i].st%60;
c=pp[2*i].ed/60;
d=pp[2*i].ed%60;
printf("%02d:%02d %02d:%02d\n",a,b,c,d);
}
else
{
a=pp[2*i+1].st/60;
b=pp[2*i+1].st%60;
c=pp[2*i+1].ed/60;
d=pp[2*i+1].ed%60;
printf("%02d:%02d %02d:%02d\n",a,b,c,d);
}
}
}
int main()
{
int i,j,k,m,p,q,g,h;
while(~scanf("%d",&n))
{
memset(head,-1,sizeof(head));tol=0;
for(i=0;i<n;i++)
{
scanf("%d:%d",&p,&q);
g=60*p+q;
scanf("%d:%d",&p,&q);
h=60*p+q;
scanf("%d",&k);
pp[2*i].st=g;
pp[2*i].ed=g+k;
pp[2*i+1].st=h-k;
pp[2*i+1].ed=h;
}
solve();
}
return 0;
}

浙公网安备 33010602011771号