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

    2-SAT 输出可行解
    找可行解的方案就是:
    根据第一次建的图建一个反图..然后求逆拓扑排序,建反图的原因是保持冲突的两个事件肯定会被染成不同的颜色
    求逆拓扑排序的原因也是为了对图染的色不会发生冲突,输出可行解就是遍历一次逆拓扑排序时染成的颜色,输出同一组颜色的解就是其中的一组可行解。
     
    代码:
      1 #include <stdio.h>
      2 #include <iostream>
      3 #include <string.h>
      4 #include <stack>
      5 #include <queue>
      6  
      7 const int maxn = 2011;
      8 const int maxm = 3000011;
      9 struct node{
     10     int u;
     11     int v;
     12     int next;
     13 }edge1[maxm], edge2[maxm];
     14 struct tt{
     15     int s;
     16     int e;
     17     int l;
     18 }tim[maxn];
     19 int n, m, cnt1, cnt2, scc_cnt, dfs_clock;
     20 int head1[maxn], head2[maxn], in[maxn], ct[maxn], ans[maxn];
     21 int sccno[maxn], dfn[maxn], low[maxn], color[maxn];
     22 std::stack<int>st;
     23  
     24 void init(){
     25     cnt1 = 0;
     26     cnt2 = 0;
     27     scc_cnt = 0;
     28     dfs_clock = 0;
     29     memset(in, 0, sizeof(in));
     30     memset(ans, 0, sizeof(ans));
     31     memset(color, 0, sizeof(color));
     32     memset(sccno, 0, sizeof(sccno));
     33     memset(dfn, 0, sizeof(dfn));
     34     memset(low, 0, sizeof(low));
     35     memset(head1, -1, sizeof(head1));
     36     memset(head2, -1, sizeof(head2));
     37 }
     38  
     39 void add(int u, int v, struct node edge[], int head[], int &cnt){
     40     edge[cnt].u = u;
     41     edge[cnt].v = v;
     42     edge[cnt].next = head[u];
     43     head[u] = cnt++;
     44 }
     45  
     46 void dfs(int u){
     47     low[u] = dfn[u] = ++dfs_clock;
     48     st.push(u);
     49     for(int i = head1[u]; i != -1; i = edge1[i].next){
     50         int v = edge1[i].v;
     51         if(!dfn[v]){
     52             dfs(v);
     53             low[u] = std::min(low[u], low[v]);
     54         }
     55         else if(!sccno[v]){
     56             low[u] = std::min(low[u], dfn[v]);
     57         }
     58     }
     59     if(low[u]==dfn[u]){
     60         ++scc_cnt;
     61         while(1){
     62             int x = st.top();
     63             st.pop();
     64             sccno[x] = scc_cnt;
     65             if(x==u) break;
     66         }
     67     }
     68 }
     69  
     70 void toposort(){
     71     std::queue<int>qu;
     72     for(int i = 1; i <= scc_cnt; i++){
     73         if(in[i]==0) qu.push(i);
     74     }
     75     while(!qu.empty()){
     76         int u = qu.front();
     77         qu.pop();
     78         if(color[u]==0){
     79             color[u] = 1;
     80             color[ct[u]] = -1;
     81         }
     82         for(int i = head2[u]; i != -1; i = edge2[i].next){
     83             int v = edge2[i].v;
     84             --in[v];
     85             if(in[v]==0) qu.push(v);
     86         }
     87     }
     88 }
     89  
     90 int main(){
     91     while(~scanf("%d", &n)){
     92         init();
     93         for(int i = 0; i < n; i++){
     94             int s1, s2, t1, t2, l;
     95             int sb = scanf("%d:%d %d:%d %d", &s1, &s2, &t1, &t2, &l);
     96             sb++;
     97             tim[i].s = s1*60+s2;
     98             tim[i].e = t1*60+t2;
     99             tim[i].l = l;
    100         }
    101         for(int i = 0; i < n; i++){
    102             for(int j = 0; j < n; j++){
    103                 if(i!=j){
    104                     if(tim[i].s<tim[j].s+tim[j].l && tim[j].s<tim[i].s+tim[i].l) add(i<<1, j<<1|1, edge1, head1, cnt1);
    105                     if(tim[i].s<tim[j].e && tim[j].e-tim[j].l<tim[i].s+tim[i].l) add(i<<1, j<<1, edge1, head1, cnt1);
    106                     if(tim[i].e-tim[i].l<tim[j].s+tim[j].l && tim[j].s<tim[i].e) add(i<<1|1, j<<1|1, edge1, head1, cnt1);
    107                     if(tim[i].e-tim[i].l<tim[j].e && tim[j].e-tim[j].l<tim[i].e) add(i<<1|1, j<<1, edge1, head1, cnt1);
    108                 }
    109             }
    110         }
    111         for(int i = 0; i < n+n; i++){
    112             if(!dfn[i]) dfs(i);
    113         }
    114         for(int i = 0; i < n+n; i++){
    115             for(int j = head1[i]; j != -1; j = edge1[j].next){
    116                 int v = edge1[j].v;
    117                 if(sccno[i] != sccno[v]){
    118                     add(sccno[v], sccno[i], edge2, head2, cnt2);
    119                     in[sccno[i]]++;
    120                 }
    121             }
    122         }
    123         bool flag = false;
    124         for(int i = 0; i < n; i++){
    125             if(sccno[i<<1]==sccno[i<<1|1]){
    126                 flag = true;
    127                 break;
    128             }
    129             ct[sccno[i<<1]] = sccno[i<<1|1];
    130             ct[sccno[i<<1|1]] = sccno[i<<1];
    131         }
    132  
    133         if(flag) puts("NO");
    134         else{
    135             toposort();
    136             for(int i = 0; i < n+n; i++){
    137                 if(color[sccno[i]]==1) ans[i] = 1;
    138             }
    139             puts("YES");
    140             for(int i = 0; i < n; i++) {
    141                 if(ans[i<<1]) printf("%02d:%02d %02d:%02d
    ", tim[i].s/60, tim[i].s%60, (tim[i].s+tim[i].l)/60, (tim[i].s+tim[i].l)%60);
    142                 else printf("%02d:%02d %02d:%02d
    ", (tim[i].e-tim[i].l)/60, (tim[i].e-tim[i].l)%60, tim[i].e/60, tim[i].e%60);
    143             }
    144         }
    145     }
    146     return 0;
    147 }
     
     
  • 相关阅读:
    暑假每周学习进度-7
    暑假每周学习进度-6
    寒假生活05
    寒假生活04
    寒假生活03
    寒假生活02
    寒假生活01
    软件设计师2019模拟小测
    第二周学习记录
    2019秋季学习计划
  • 原文地址:https://www.cnblogs.com/pony1993/p/3430069.html
Copyright © 2011-2022 走看看