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 }

 

 
 
posted on 2013-11-18 19:25  pony1993  阅读(433)  评论(0编辑  收藏  举报

View My Stats