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\n", 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\n", (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 }

 

 
 

你可能感兴趣的:(poj)