POJ 3683 2-SAT 输出方案

                                                                                    Priest John's Busiest Day













Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 7216Accepted: 2464Special
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;
}
posted @ 2013-09-04 00:14  线性无关  阅读(157)  评论(0)    收藏  举报