码迷,mamicode.com
首页 > 其他好文 > 详细

poj 3683 Priest John's Busiest Day - 2-sat

时间:2017-07-11 12:50:05      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:fst   exit   tac   tin   ddd   2-sat   i++   either   int   

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 Sito 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 Sito 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 SiTi and DiSi 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

  2-sat输出任意解。缩点缩完后,建反图,拓扑排序。

  注意端点的问题,任意两人的婚礼时间不能重叠。

Code

  1 /**
  2  * poj
  3  * Problem#3683
  4  * Accepted
  5  * Time:172ms
  6  * Memory:17132k
  7  */
  8 #include <iostream>
  9 #include <cstdio>
 10 #include <ctime>
 11 #include <cmath>
 12 #include <cctype>
 13 #include <cstring>
 14 #include <cstdlib>
 15 #include <fstream>
 16 #include <sstream>
 17 #include <algorithm>
 18 #include <map>
 19 #include <set>
 20 #include <stack>
 21 #include <queue>
 22 #include <vector>
 23 #include <stack>
 24 #ifndef WIN32
 25 #define Auto "%lld"
 26 #else
 27 #define Auto "%I64d"
 28 #endif
 29 using namespace std;
 30 typedef bool boolean;
 31 const signed int inf = (signed)((1u << 31) - 1);
 32 const double eps = 1e-6;
 33 const int binary_limit = 128;
 34 #define smin(a, b) a = min(a, b)
 35 #define smax(a, b) a = max(a, b)
 36 #define max3(a, b, c) max(a, max(b, c))
 37 #define min3(a, b, c) min(a, min(b, c))
 38 template<typename T>
 39 inline boolean readInteger(T& u){
 40     char x;
 41     int aFlag = 1;
 42     while(!isdigit((x = getchar())) && x != - && x != -1);
 43     if(x == -1) {
 44         ungetc(x, stdin);    
 45         return false;
 46     }
 47     if(x == -){
 48         x = getchar();
 49         aFlag = -1;
 50     }
 51     for(u = x - 0; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - 0);
 52     ungetc(x, stdin);
 53     u *= aFlag;
 54     return true;
 55 }
 56 
 57 ///map template starts
 58 typedef class Edge{
 59     public:
 60         int end;
 61         int next;
 62         Edge(const int end = 0, const int next = 0):end(end), next(next){}
 63 }Edge;
 64 
 65 typedef class MapManager{
 66     public:
 67         int ce;
 68         int *h;
 69         vector<Edge> edge;
 70         MapManager(){}
 71         MapManager(int points):ce(0){
 72             h = new int[(const int)(points + 1)];
 73             memset(h, 0, sizeof(int) * (points + 1));
 74             edge.push_back(Edge());
 75         }
 76         inline void addEdge(int from, int end){
 77 //            printf("%d->%d\n", from, end);
 78             edge.push_back(Edge(end, h[from]));
 79             h[from] = ++ce;
 80         }
 81         inline void addDoubleEdge(int from, int end){
 82             addEdge(from, end);
 83             addEdge(end, from);
 84         }
 85         Edge& operator [] (int pos) {
 86             return edge[pos];
 87         }
 88 }MapManager;
 89 #define m_begin(g, i) (g).h[(i)]
 90 ///map template ends
 91 
 92 int n;
 93 MapManager g;
 94 int *ls, *rs, *lasts;
 95 
 96 inline int readTime() {
 97     static int a, b;
 98     readInteger(a);
 99     readInteger(b);
100     return a * 60 + b;
101 }
102 
103 boolean isOn(int l1, int r1, int l2, int r2) {
104 //    printf("checking:[%d, %d][%d, %d]\n", l1, r1, l2, r2);
105     return !(r1 <= l2 || l1 >= r2);        // Notice that use ‘<=‘ and ‘>=‘ instead of ‘<‘ and ‘>‘
106 }
107 
108 inline void init() {
109     readInteger(n);
110     ls = new int[n + 1];
111     rs = new int[n + 1];
112     lasts = new int[n + 1];
113     for(int i = 1; i <= n; i++) {
114         ls[i] = readTime();
115         rs[i] = readTime();
116         readInteger(lasts[i]);
117     }
118 }
119 
120 inline void init_map() {
121     g = MapManager(2 * n + 3);
122     for(int i = 1; i < n; i++) {
123         for(int j = i + 1; j <= n; j++) {
124             if(isOn(ls[i], ls[i] + lasts[i], ls[j], ls[j] + lasts[j])) {
125                 g.addEdge(2 * i - 1, 2 * j);
126                 g.addEdge(2 * j - 1, 2 * i);
127             }
128             if(isOn(ls[i], ls[i] + lasts[i], rs[j] - lasts[j], rs[j])) {
129                 g.addEdge(2 * i - 1, 2 * j - 1);
130                 g.addEdge(2 * j, 2 * i);
131             }
132             if(isOn(rs[i] - lasts[i], rs[i], ls[j], ls[j] + lasts[j])) {
133                 g.addEdge(2 * i, 2 * j);
134                 g.addEdge(2 * j - 1, 2 * i - 1);
135             }
136             if(isOn(rs[i] - lasts[i], rs[i], rs[j] - lasts[j], rs[j])) {
137                 g.addEdge(2 * i, 2 * j - 1);
138                 g.addEdge(2 * j, 2 * i - 1);
139             }
140         }
141     }
142 }
143 
144 int cnt = 0, scc = 0;
145 int* visitID;
146 int* exitID;
147 boolean* visited;
148 boolean* instack;
149 stack<int> s;
150 int* belong;
151 inline void init_tarjan() {
152     int an = 2 * n + 3;
153     visitID = new int[(an)];
154     exitID = new int[(an)];
155     visited = new boolean[(an)];
156     instack = new boolean[(an)];
157     belong = new int[(an)];
158     memset(visited, false, sizeof(boolean) * an);
159     memset(instack, false, sizeof(boolean) * an);
160 }
161 
162 void tarjan(int node) {
163     visitID[node] = exitID[node] = cnt++;
164     visited[node] = instack[node] = true;
165     s.push(node);
166     
167     for(int i = m_begin(g, node); i; i = g[i].next) {
168         int& e = g[i].end;
169         if(!visited[e]) {
170             tarjan(e);
171             smin(exitID[node], exitID[e]);
172         } else if(instack[e]) {
173             smin(exitID[node], visitID[e]);
174         }
175     }
176     
177     if(visitID[node] == exitID[node]) {
178         int now = -1;
179         scc++;
180         while(now != node) {
181             now = s.top();
182             s.pop();
183             instack[now] = false;
184             belong[now] = scc;
185         }
186     }
187 }
188 
189 int* opp;
190 int* col;
191 int* dag;
192 MapManager rg;
193 inline void rebuild() {
194     delete[] visitID;
195     delete[] exitID;
196     delete[] visited;
197     delete[] instack;
198     
199     rg = MapManager(scc);
200     col = new int[(scc + 1)];
201     opp = new int[(scc + 1)];
202     dag = new int[(scc + 1)];
203     memset(col, 0, sizeof(int) * (scc + 1));
204     memset(dag, 0, sizeof(int) * (scc + 1));
205     for(int i = 1; i <= (2 * n); i++) {
206         if(i & 1) opp[belong[i]] = belong[i + 1];
207         else opp[belong[i]] = belong[i - 1];
208         for(int j = m_begin(g, i); j; j = g[j].next) {
209             if(belong[i] != belong[g[j].end])
210                 rg.addEdge(belong[g[j].end], belong[i]), dag[belong[i]]++;
211         }
212     }
213 }
214 
215 void dfs(int node) {
216     if(col[node])    return;
217     col[node] = 2;
218     for(int i = m_begin(rg, node); i; i = rg[i].next)
219         dfs(rg[i].end);
220 }
221 
222 queue<int> que;
223 inline void topu() {
224     for(int i = 1; i <= scc; i++) {
225         if(!dag[i])
226             que.push(i);
227     }
228     while(!que.empty()) {
229         int e = que.front();
230         que.pop();
231         if(col[e])    continue;
232         col[e] = 1;
233         dfs(opp[e]);
234         for(int i = m_begin(rg, e); i; i = rg[i].next) {
235             int& eu = rg[i].end;
236             dag[eu]--;
237             if(dag[eu] == 0)
238                 que.push(eu);
239         }
240     }
241 }
242 
243 inline void check() {
244     for(int i = 1; i < (n << 1); i += 2)
245         if(belong[i] == belong[i + 1]) {
246             puts("NO");
247             exit(0);
248         }
249 }
250 
251 inline void printTime(int x) {
252     printf("%.2d:%.2d", x / 60, x % 60);
253 }
254 
255 inline void solve() {
256     puts("YES");
257     for(int i = 1; i <= n; i++) {
258         if(col[belong[i * 2 - 1]] == 1)    printTime(ls[i]), putchar( ), printTime(ls[i] + lasts[i]);
259         else printTime(rs[i] - lasts[i]), putchar( ), printTime(rs[i]);
260         putchar(\n);
261     }
262 }
263 
264 int main() {
265     init();
266     init_map();
267     init_tarjan();
268     for(int i = 1; i <= 2 * n; i++)
269         if(!visited[i])
270             tarjan(i);
271     check();
272     rebuild();
273     topu();
274     solve();
275     return 0;
276 }

poj 3683 Priest John's Busiest Day - 2-sat

标签:fst   exit   tac   tin   ddd   2-sat   i++   either   int   

原文地址:http://www.cnblogs.com/yyf0309/p/7149908.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!