POJ 3683 - Priest John's Busiest Day 构图2-sat..感觉求方案不太正确..要改进..

来源:互联网 发布:淘宝一千多的充气娃娃 编辑:程序博客网 时间:2024/06/05 09:05

               题意:

                       在一个乡村有一个牧师John...有天很多人要举行婚礼..需要John来进行祷告..祷告必须要在婚礼开始时到开始后D时间段..或者到婚礼结束的最后D时间段..现在给出每个婚礼开始和结束的时间..以及每场婚礼需要祷告的时间长度...问所有婚礼是否能顺利进行..如果可以..输出任意一种牧师John祷告的时间方案...

               题解:

                       对于一场婚礼.要么是前面的一段..要么是后面的一段..符合2-sat的基本模型..然后根据时间冲突的关系构造有向边...用tarjan判断是否有可行解..最后dfs染色找到答案..话说我越来越觉得我染色的那部分有bug...就算几个题都切过去了...但真的有很大问题!!!


Program:

#include<iostream>#include<stdio.h>#include<cmath>#include<queue>#include<stack>#include<string.h>#include<map>#include<set>#include<algorithm>#define oo 1000000007#define MAXN 1005<<1#define MAXM 1000005<<1#define ll long longusing namespace std; struct couple{       int t1,t2,d; }C[MAXN];struct node{       int x,y,next; }line[MAXM];set<int> T[MAXN];int Lnum,_next[MAXN],dfn[MAXN],low[MAXN],tp[MAXN],tpnum,DfsIndex,color[MAXN];bool instack[MAXN],d[MAXN];stack<int> mystack;void addline(int x,int y){       line[++Lnum].next=_next[x],_next[x]=Lnum;       line[Lnum].x=x,line[Lnum].y=y;}bool legal(int s1,int t1,int s2,int t2){       if (s2<=s1 && s1<t2) return false;       if (s2<t1 && t1<=t2) return false;       if (s1<=s2 && s2<t1) return false;       if (s1<t2 && t2<=t1) return false;       return true;}void tarjan(int x){       int y,k;       dfn[x]=low[x]=++DfsIndex;       instack[x]=true,mystack.push(x);       for (k=_next[x];k;k=line[k].next)       {               y=line[k].y;               if (!dfn[y])               {                   tarjan(y);                   low[x]=min(low[x],low[y]);               }else               if (instack[y])                   low[x]=min(low[x],dfn[y]);       }       if (low[x]==dfn[x])       {               tpnum++;               do               {                       x=mystack.top();                       mystack.pop();                       instack[x]=false;                       tp[x]=tpnum;               }while (low[x]!=dfn[x]);       }}bool judge(int n){       for (int i=0;i<n;i++)          if (tp[i<<1]==tp[i<<1|1]) return false;       return true;}void dfs(int x){       if (color[x]) return;       color[x]=1;       for(set<int>::iterator i=T[x].begin();i!=T[x].end();i++) color[*i]=2;       for (int k=_next[x];k;k=line[k].next)           dfs(line[k].y); }int main(){             int N,i,j;        scanf("%d",&N);       for (i=0;i<N;i++)        {             int h,m;             scanf("%d:%d",&h,&m);              C[i].t1=h*60+m;             scanf("%d:%d%d",&h,&m,&C[i].d);              C[i].t2=h*60+m;       }       memset(_next,0,sizeof(_next));       Lnum=0;       for (i=0;i<N;i++)           for (j=i+1;j<N;j++)           {                   if (!legal(C[i].t1,C[i].t1+C[i].d,C[j].t1,C[j].t1+C[j].d))                      addline(i<<1,j<<1|1),addline(j<<1,i<<1|1);                 if (!legal(C[i].t1,C[i].t1+C[i].d,C[j].t2-C[j].d,C[j].t2))                      addline(i<<1,j<<1),addline(j<<1|1,i<<1|1);                 if (!legal(C[i].t2-C[i].d,C[i].t2,C[j].t1,C[j].t1+C[j].d))                      addline(i<<1|1,j<<1|1),addline(j<<1,i<<1);                 if (!legal(C[i].t2-C[i].d,C[i].t2,C[j].t2-C[j].d,C[j].t2))                      addline(i<<1|1,j<<1),addline(j<<1|1,i<<1);           }       memset(dfn,0,sizeof(dfn));       memset(instack,false,sizeof(instack));       while (!mystack.empty()) mystack.pop();       DfsIndex=tpnum=0;       for (i=0;i<(N<<1);i++)          if (!dfn[i]) tarjan(i);       if (!judge(N)) printf("NO\n");           else            {                   printf("YES\n");                   int temp=Lnum;                   Lnum=0;                   memset(_next,0,sizeof(_next));                   memset(d,true,sizeof(d));                   for (i=1;i<=tpnum;i++) T[i].clear();                   for (i=0;i<(N<<1);i++) T[tp[i]].insert(tp[i^1]);                   for (i=1;i<=temp;i++)                   {                           int x=tp[line[i].x],y=tp[line[i].y];                           if (x==y) continue;                           addline(x,y),d[y]=false;                   }                   do                   {                         memset(color,0,sizeof(color));                         for (i=1;i<=tpnum;i++)                            if (!color[i]) dfs(i);                         for (i=0;i<N;i++)                            if (color[tp[i<<1]]==color[tp[i<<1|1]]) break;                    }while (i!=N);                   for (i=0;i<N;i++)                   {                         int h,m;                         if (color[tp[i<<1]]==1)                         {                                 h=C[i].t1/60,m=C[i].t1%60;                                 if (h<10) printf("0%d:",h); else printf("%d:",h);                                 if (m<10) printf("0%d ",m); else printf("%d ",m);                                 h=(C[i].t1+C[i].d)/60,m=(C[i].t1+C[i].d)%60;                                 if (h<10) printf("0%d:",h); else printf("%d:",h);                                 if (m<10) printf("0%d\n",m); else printf("%d\n",m);                                                         }else                         {                                 h=(C[i].t2-C[i].d)/60,m=(C[i].t2-C[i].d)%60;                                 if (h<10) printf("0%d:",h); else printf("%d:",h);                                 if (m<10) printf("0%d ",m); else printf("%d ",m);                                   h=C[i].t2/60,m=C[i].t2%60;                                 if (h<10) printf("0%d:",h); else printf("%d:",h);                                 if (m<10) printf("0%d\n",m); else printf("%d\n",m);                                                            }                   }           }       return 0;} 


原创粉丝点击