http://poj.org/problem?id=3683
题意:
有n个婚礼,每个婚礼有起始时间si,结束时间ti,还有一个主持时间ti,ti必须安排在婚礼的开始或者结束,
主持由祭祀来做,但是只有一个祭祀,所以 各个婚礼的主持时间不能重复,问你有没有可能正常的安排主持时间,
不能输出no,能的话要输出具体的答案:即每个婚礼的主持时间段是什么样的。
2-sat 问题。建图:
对于每个婚礼,主持时间只有两种状态,而且各个婚礼之间的主持时间之间有相互限制,自然想到2-sat。
对于婚礼i和婚礼j。i表示在开始主持,i2表示在结束主持,j类似。
枚举每一对不同的i和j。
如果i和j冲突。连接i j2
如果i和j2冲突,连接i j
如果i2和j冲突,连接i2 j2
如果i2和j2冲突,连接i2 j
然后就是Tarjan求强联通,判断2-sat问题,成立的话,topsort,输出答案。
1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define eps 1e-12
15 #define inf 100000000
16 #define mx 1<<60
17 #define ll __int64
18 const double pi = acos(-1.0);
19 const int maxn = 1200;
20 using namespace std;
21 int top,num,bcnt,belong[maxn*2],instack[maxn*2],stack[maxn*2],dfn[maxn*2],low[maxn*2];
22 int n ,m;
23 int opp[maxn * 2],col[maxn * 2],in[maxn*2],head[maxn*2];
24 int ans[maxn*2] ;
25 struct pnode
26 {
27 int from ;
28 int to;
29 int next;
30 }p[maxn*maxn],eg[maxn*maxn];
31
32 int cnt ,next[maxn*2];
33 void add(int u,int v)
34 {
35 p[cnt].from = u;
36 p[cnt].to = v;
37 p[cnt].next = next[u];
38 next[u] = cnt++;
39
40 }
41
42 void tarjan(int i)//tarjan 求强联通 分量
43 {
44 int j,k;
45 dfn[i] = low[i] = ++num;
46 stack[++top] = i;
47 instack[i] = 1;
48 for(k = next[i] ; k != -1;k = p[k].next)
49 {
50
51 j = p[k].to ;
52 if(!dfn[j])
53 {
54 tarjan(j);
55 if(low[j] < low[i]) low[i] = low[j] ;
56 }
57 else
58 {
59 if(instack[j] && dfn[j] < low[i]) low[i] = dfn[j] ;
60 }
61
62 }
63 if(dfn[i] == low[i])
64 {
65 bcnt++;
66 do
67 {
68 j = stack[top--];
69 instack[j] = 0 ;
70 belong[j] = bcnt ;
71 }while(j != i);
72 }
73 }
74 void insert(int u,int v)
75 {
76 eg[num].from = u;
77 eg[num].to = v;
78 eg[num].next = head[u];
79 head[u] = num++;
80 }
81 bool solve()//tarjan + topsort染色输出
82 {
83 int i, l;
84 for(i =0 ; i <= n*2;i++)
85 {
86 dfn[i] = low[i] = instack[i] = stack[i] = belong[i] = 0;
87 }
88 top = bcnt = num = 0;
89 for(i = 0 ; i < n*2;i++)
90 {
91 if(!dfn[i])tarjan(i);
92 }
93 for(i =0 ;i< n;i++)
94 {
95 if(belong[i] == belong[i + n]) return false ;//判断是否 有解
96
97 opp[belong[i]] = belong[i + n];//记录 对立 点的位置
98 opp[belong[i+n]] = belong[i] ;
99 }
100 //下面重新构图
101 CL(col,0);
102 CL(in,0);
103 CL(head,-1);
104 num = 0;
105 for(i = 0 ; i < cnt ;i++)
106 {
107 if(belong[p[i].from] != belong[p[i].to])
108 {
109 insert(belong[p[i].to],belong[p[i].from]);// (将 缩点 )反向建图
110 in[belong[p[i].from]]++;//记录每个点的入度
111 }
112 }
113 queue<int>que;
114 for(i = 0 ;i < bcnt;i++)//将入度为0 的点 入队列
115 {
116 if(in[i] == 0) {que.push(i);}
117 }
118 while(!que.empty())
119 {
120 int k = que.front();que.pop();
121
122 if(col[k] == 0)
123 {
124 col[k] = 1;//染为 红色
125 col[opp[k]] = -1;// 将 对立点染为 绿色
126
127
128 }
129 for(i = head[k];i!=-1;i = eg[i].next)
130 {
131 int v = eg[i].to;
132 in[v]--;
133 if(in[v] == 0)que.push(v) ;
134
135 }
136
137
138 }
139 CL(ans,0);
140 for(i = 0 ; i < 2*n;i++)
141 {
142 if(col[belong[i]] == 1)//标记 染为 红色的 点 ,
143 {
144 ans[i] = 1;
145 }
146 }
147
148 return true;
149
150
151 }
152 void init()
153 {
154 CL(next,-1);
155 cnt = 0 ;
156
157 }
158 struct node
159 {
160 int from;
161 int to;
162 int len ;
163 }q[maxn] ;
164 int judge( char *c)
165 {
166 int a,b;
167 sscanf(c,"%d:%d",&a,&b);
168
169 return a*60 + b ;
170
171
172 }
173 int judge1(int a,int b,int c,int d)
174 {
175
176 if(b <= c || d <= a) return 0;
177
178 return 1;
179 }
180 void pf(int x)
181 {
182 printf("%02d:%02d",x/60,x%60) ;
183 }
184 int main()
185 {
186 int i,j,a,b,c;
187
188 //freopen("data.txt","r",stdin) ;
189 char str1[10],str2[10];
190 while(scanf("%d",&n)!=EOF)
191 {
192 init() ;
193 for(i = 0;i < n;i++)
194 {
195 scanf("%s %s %d",str1,str2,&q[i].len);
196
197 q[i].from = judge(str1);
198
199 q[i].to = judge(str2);
200
201
202
203
204 }
205
206 for(i = 0 ;i < n;i++)
207 {
208 for(j = 0;j < n;j++)
209 {
210 if(i == j)continue ;
211 if(judge1(q[i].from,q[i].from + q[i].len,q[j].from,q[j].from + q[j].len))
212 {
213 add(i,j+n);
214
215
216
217 }
218 if(judge1(q[i].from,q[i].from + q[i].len,q[j].to - q[j].len,q[j].to ))
219 {
220 add(i,j);
221
222
223
224 }
225 if(judge1(q[i].to - q[i].len,q[i].to,q[j].from,q[j].from + q[j].len))
226 {
227 add(i + n,j+n);
228
229
230
231 }
232 if(judge1(q[i].to - q[i].len,q[i].to,q[j].to - q[j].len,q[j].to ))
233 {
234 add(i + n,j);
235
236
237
238 }
239 }
240 }
241
242 bool f = solve();
243 if(f)
244 {
245 puts("YES");
246 for(i =0 ; i< n;i++)
247 {
248 if(ans[i])
249 {
250 pf(q[i].from);printf(" ");
251 pf(q[i].from + q[i].len);
252 puts("");
253 }
254 else
255 {
256 pf(q[i].to - q[i].len);printf(" ");
257 pf(q[i].to);
258 puts("");
259 }
260 }
261 }
262 else puts("NO");
263
264 }
265 }
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define eps 1e-12
15 #define inf 100000000
16 #define mx 1<<60
17 #define ll __int64
18 const double pi = acos(-1.0);
19 const int maxn = 1200;
20 using namespace std;
21 int top,num,bcnt,belong[maxn*2],instack[maxn*2],stack[maxn*2],dfn[maxn*2],low[maxn*2];
22 int n ,m;
23 int opp[maxn * 2],col[maxn * 2],in[maxn*2],head[maxn*2];
24 int ans[maxn*2] ;
25 struct pnode
26 {
27 int from ;
28 int to;
29 int next;
30 }p[maxn*maxn],eg[maxn*maxn];
31
32 int cnt ,next[maxn*2];
33 void add(int u,int v)
34 {
35 p[cnt].from = u;
36 p[cnt].to = v;
37 p[cnt].next = next[u];
38 next[u] = cnt++;
39
40 }
41
42 void tarjan(int i)//tarjan 求强联通 分量
43 {
44 int j,k;
45 dfn[i] = low[i] = ++num;
46 stack[++top] = i;
47 instack[i] = 1;
48 for(k = next[i] ; k != -1;k = p[k].next)
49 {
50
51 j = p[k].to ;
52 if(!dfn[j])
53 {
54 tarjan(j);
55 if(low[j] < low[i]) low[i] = low[j] ;
56 }
57 else
58 {
59 if(instack[j] && dfn[j] < low[i]) low[i] = dfn[j] ;
60 }
61
62 }
63 if(dfn[i] == low[i])
64 {
65 bcnt++;
66 do
67 {
68 j = stack[top--];
69 instack[j] = 0 ;
70 belong[j] = bcnt ;
71 }while(j != i);
72 }
73 }
74 void insert(int u,int v)
75 {
76 eg[num].from = u;
77 eg[num].to = v;
78 eg[num].next = head[u];
79 head[u] = num++;
80 }
81 bool solve()//tarjan + topsort染色输出
82 {
83 int i, l;
84 for(i =0 ; i <= n*2;i++)
85 {
86 dfn[i] = low[i] = instack[i] = stack[i] = belong[i] = 0;
87 }
88 top = bcnt = num = 0;
89 for(i = 0 ; i < n*2;i++)
90 {
91 if(!dfn[i])tarjan(i);
92 }
93 for(i =0 ;i< n;i++)
94 {
95 if(belong[i] == belong[i + n]) return false ;//判断是否 有解
96
97 opp[belong[i]] = belong[i + n];//记录 对立 点的位置
98 opp[belong[i+n]] = belong[i] ;
99 }
100 //下面重新构图
101 CL(col,0);
102 CL(in,0);
103 CL(head,-1);
104 num = 0;
105 for(i = 0 ; i < cnt ;i++)
106 {
107 if(belong[p[i].from] != belong[p[i].to])
108 {
109 insert(belong[p[i].to],belong[p[i].from]);// (将 缩点 )反向建图
110 in[belong[p[i].from]]++;//记录每个点的入度
111 }
112 }
113 queue<int>que;
114 for(i = 0 ;i < bcnt;i++)//将入度为0 的点 入队列
115 {
116 if(in[i] == 0) {que.push(i);}
117 }
118 while(!que.empty())
119 {
120 int k = que.front();que.pop();
121
122 if(col[k] == 0)
123 {
124 col[k] = 1;//染为 红色
125 col[opp[k]] = -1;// 将 对立点染为 绿色
126
127
128 }
129 for(i = head[k];i!=-1;i = eg[i].next)
130 {
131 int v = eg[i].to;
132 in[v]--;
133 if(in[v] == 0)que.push(v) ;
134
135 }
136
137
138 }
139 CL(ans,0);
140 for(i = 0 ; i < 2*n;i++)
141 {
142 if(col[belong[i]] == 1)//标记 染为 红色的 点 ,
143 {
144 ans[i] = 1;
145 }
146 }
147
148 return true;
149
150
151 }
152 void init()
153 {
154 CL(next,-1);
155 cnt = 0 ;
156
157 }
158 struct node
159 {
160 int from;
161 int to;
162 int len ;
163 }q[maxn] ;
164 int judge( char *c)
165 {
166 int a,b;
167 sscanf(c,"%d:%d",&a,&b);
168
169 return a*60 + b ;
170
171
172 }
173 int judge1(int a,int b,int c,int d)
174 {
175
176 if(b <= c || d <= a) return 0;
177
178 return 1;
179 }
180 void pf(int x)
181 {
182 printf("%02d:%02d",x/60,x%60) ;
183 }
184 int main()
185 {
186 int i,j,a,b,c;
187
188 //freopen("data.txt","r",stdin) ;
189 char str1[10],str2[10];
190 while(scanf("%d",&n)!=EOF)
191 {
192 init() ;
193 for(i = 0;i < n;i++)
194 {
195 scanf("%s %s %d",str1,str2,&q[i].len);
196
197 q[i].from = judge(str1);
198
199 q[i].to = judge(str2);
200
201
202
203
204 }
205
206 for(i = 0 ;i < n;i++)
207 {
208 for(j = 0;j < n;j++)
209 {
210 if(i == j)continue ;
211 if(judge1(q[i].from,q[i].from + q[i].len,q[j].from,q[j].from + q[j].len))
212 {
213 add(i,j+n);
214
215
216
217 }
218 if(judge1(q[i].from,q[i].from + q[i].len,q[j].to - q[j].len,q[j].to ))
219 {
220 add(i,j);
221
222
223
224 }
225 if(judge1(q[i].to - q[i].len,q[i].to,q[j].from,q[j].from + q[j].len))
226 {
227 add(i + n,j+n);
228
229
230
231 }
232 if(judge1(q[i].to - q[i].len,q[i].to,q[j].to - q[j].len,q[j].to ))
233 {
234 add(i + n,j);
235
236
237
238 }
239 }
240 }
241
242 bool f = solve();
243 if(f)
244 {
245 puts("YES");
246 for(i =0 ; i< n;i++)
247 {
248 if(ans[i])
249 {
250 pf(q[i].from);printf(" ");
251 pf(q[i].from + q[i].len);
252 puts("");
253 }
254 else
255 {
256 pf(q[i].to - q[i].len);printf(" ");
257 pf(q[i].to);
258 puts("");
259 }
260 }
261 }
262 else puts("NO");
263
264 }
265 }