zoukankan      html  css  js  c++  java
  • poj 3683 Priest John's Busiest Day

    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
    ", 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]
    ", 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('
    ');
    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 }
  • 相关阅读:
    Excel 常用函数
    Excel中使用VBA访问Access数据库
    Python 日期和时间戳的转换
    tensorflow中命名空间、变量命名的问题
    Git:一个简单示例
    Pyhon中运算符的使用
    python中模块包的离线下载教程
    python中的进制转换
    python几种常见的模块安装方法
    python中的模块调用
  • 原文地址:https://www.cnblogs.com/yyf0309/p/7149908.html
Copyright © 2011-2022 走看看