[题解]POJ 3683 Priest John's Busiest Day
【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---------------------------------------------------------------------------------------------------------------------------------
【題目大意】
有n場婚禮,每場婚禮有對應的開始和結束時間,每場婚禮都需要舉行一場儀式,儀式持續時間為Di。儀式可以在婚禮前舉行[Si,Si+Di],或者在婚禮后舉行[Ti-Di,Ti]。要求每個婚禮的儀式不沖突,求一組儀式時間安排的可行解。
【題解】
裸的2-SAT問題。主要是建圖,注意判斷哪些方案會出現矛盾。其它為2-SAT的基礎代碼。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 using namespace std; 6 #define MAXN 1020*2 7 int n; 8 struct Thing 9 { 10 int st,ed,Len; 11 }p[MAXN]; 12 struct node 13 { 14 int v; 15 node *next; 16 }; 17 node edge[MAXN*MAXN]; 18 node *cnt=&edge[0]; 19 node *adj[MAXN]; 20 node edge2[MAXN*MAXN]; 21 node *cnt2=&edge2[0]; 22 node *adj2[MAXN]; 23 int dfn[MAXN],low[MAXN],dcnt; 24 int Belong[MAXN],Num[MAXN]; 25 int stack[MAXN],top; 26 int In[MAXN],opp[MAXN],scc; 27 int q[MAXN],col[MAXN]; 28 bool Instack[MAXN],ans[MAXN]; 29 char s1[10],s2[10]; 30 inline void Addedge(int u,int v) 31 { 32 node *p=++cnt; 33 p->v=v; 34 p->next=adj[u]; 35 adj[u]=p; 36 } 37 inline void Addedge2(int u,int v) 38 { 39 node *p=++cnt2; 40 p->v=v; 41 p->next=adj2[u]; 42 adj2[u]=p; 43 } 44 inline int Cal(char str[]) 45 { 46 int Ret=((str[0]-'0')*10+str[1]-'0')*60+(str[3]-'0')*10+str[4]-'0'; 47 return Ret; 48 } 49 inline bool Check(int st1,int len1,int st2,int len2) 50 { 51 return (st2<st1+len1)&&(st1<st2+len2); 52 } 53 void Read() 54 { 55 //scanf("%d",&n); 56 int i; 57 for(i=1;i<=n;i++) 58 { 59 scanf("%s%s%d",s1,s2,&p[i].Len); 60 p[i].st=Cal(s1); 61 p[i].ed=Cal(s2); 62 } 63 } 64 void Build_map() 65 { 66 int i,j; 67 for(i=1;i<=n;i++) 68 for(j=1;j<=n;j++) 69 { 70 if(i==j) 71 continue; 72 if(Check(p[i].st,p[i].Len,p[j].st,p[j].Len)) 73 Addedge(i,j+n); 74 if(Check(p[i].st,p[i].Len,p[j].ed-p[j].Len,p[j].Len)) 75 Addedge(i,j); 76 if(Check(p[i].ed-p[i].Len,p[i].Len,p[j].st,p[j].Len)) 77 Addedge(i+n,j+n); 78 if(Check(p[i].ed-p[i].Len,p[i].Len,p[j].ed-p[j].Len,p[j].Len)) 79 Addedge(i+n,j); 80 } 81 } 82 void Tarjan(int u) 83 { 84 int v; 85 dfn[u]=low[u]=++dcnt; 86 stack[++top]=u; 87 Instack[u]=true; 88 for(node *p=adj[u];p;p=p->next) 89 { 90 v=p->v; 91 if(!dfn[v]) 92 { 93 Tarjan(v); 94 low[u]=min(low[u],low[v]); 95 } 96 else if(Instack[v]) 97 low[u]=min(low[u],dfn[v]); 98 } 99 if(dfn[u]==low[u]) 100 { 101 scc++; 102 do 103 { 104 v=stack[top]; 105 top--; 106 Instack[v]=false; 107 Belong[v]=scc; 108 Num[scc]++; 109 }while(v!=u); 110 } 111 } 112 bool Work() 113 { 114 int i; 115 for(i=1;i<=n*2;i++) 116 if(!dfn[i]) 117 Tarjan(i); 118 for(i=1;i<=n;i++) 119 { 120 if(Belong[i]==Belong[i+n]) 121 return false; 122 opp[Belong[i]]=Belong[i+n]; 123 opp[Belong[i+n]]=Belong[i]; 124 } 125 int u,v; 126 for(i=1;i<=n*2;i++) 127 for(node *p=adj[i];p;p=p->next) 128 { 129 v=p->v; 130 if(Belong[i]!=Belong[v]) 131 { 132 Addedge2(Belong[v],Belong[i]); 133 In[Belong[i]]++; 134 } 135 } 136 int l=0,r=0; 137 for(i=1;i<=scc;i++) 138 if(!In[i]) 139 { 140 q[r]=i; 141 r++; 142 } 143 while(l<r) 144 { 145 u=q[l]; 146 l++; 147 if(!col[u]) 148 { 149 col[u]=1; 150 col[opp[u]]=-1; 151 } 152 for(node *p=adj2[u];p;p=p->next) 153 { 154 v=p->v; 155 In[v]--; 156 if(!In[v]) 157 { 158 q[r]=v; 159 r++; 160 } 161 } 162 } 163 for(i=1;i<=n;i++) 164 if(col[Belong[i]]==1) 165 ans[i]=true; 166 return true; 167 } 168 void Print() 169 { 170 if(Work()) 171 { 172 printf("YES\n"); 173 int i; 174 for(i=1;i<=n;i++) 175 { 176 if(ans[i]) 177 printf("%02d:%02d %02d:%02d\n",p[i].st/60,p[i].st%60,(p[i].st+p[i].Len)/60,(p[i].st+p[i].Len)%60); 178 else 179 printf("%02d:%02d %02d:%02d\n",(p[i].ed-p[i].Len)/60,(p[i].ed-p[i].Len)%60,p[i].ed/60,p[i].ed%60); 180 } 181 } 182 else 183 printf("NO\n"); 184 } 185 inline void Pre() 186 { 187 memset(edge,0,sizeof(edge)); 188 memset(adj,0,sizeof(adj)); 189 cnt=&edge[0]; 190 memset(edge2,0,sizeof(edge2)); 191 memset(adj2,0,sizeof(adj2)); 192 cnt2=&edge2[0]; 193 memset(dfn,0,sizeof(dfn)); 194 memset(low,0,sizeof(low)); 195 dcnt=0; 196 top=0; 197 memset(Instack,false,sizeof(Instack)); 198 memset(Belong,0,sizeof(Belong)); 199 memset(Num,0,sizeof(Num)); 200 scc=0; 201 memset(opp,0,sizeof(opp)); 202 memset(In,0,sizeof(In)); 203 memset(q,0,sizeof(q)); 204 memset(col,0,sizeof(col)); 205 memset(ans,false,sizeof(ans)); 206 } 207 int main() 208 { 209 //freopen("Data.in","r",stdin); 210 //freopen("Data.out","w",stdout); 211 while(scanf("%d",&n)!=EOF) 212 { 213 Pre(); 214 Read(); 215 Build_map(); 216 Print(); 217 } 218 return 0; 219 }
?
轉載于:https://www.cnblogs.com/CQBZOIer-zyy/archive/2013/01/22/2872211.html
總結
以上是生活随笔為你收集整理的[题解]POJ 3683 Priest John's Busiest Day的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WCF IE 能够正常访问,chrome
- 下一篇: PIN码PJ