POJ 3683 Priest John's Busiest Day 2-Sat
Posted horsepower2001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3683 Priest John's Busiest Day 2-Sat相关的知识,希望对你有一定的参考价值。
矛盾判断:
对于婚礼现场 x 和 y,x 的第一段可以和 y 的第一段或者第二段矛盾,同理,x 的第二段可以和 y 的第一段或者第二段矛盾,条件是 x 的 1或2 段与 y 的 1或2 段有重合,那么选了 x 某一段就不能选择其矛盾的那一段,那就只能选择 y 中的另一段,建立一条 x (u)-> y ( v的对立 ),同理,x (u的对立)<- y ( v ) 。
真的,2-sat千万不要用邻接链表!!!卡死卡死卡死!!!稠密图!!!不要用!!!
我WA和RE和MLE都怪邻接矩阵!!!!!!!!!!!!!!!!!!!!!!!!!
总代码:
下面第一个代码纪念邻接矩阵这个垃圾的Failure!
1 #include <cstdio>
2 #include <stack>
3 #include <queue>
4 #include <cstring>
5
6 const int N = 2000000 + 5 ;
7
8 std :: stack < int > s ;
9 std :: queue < int > q ;
10
11 struct ConfirmedHY {
12 int st ;
13 int en ;
14 }
15 dot [ N ] ;
16
17 int head [ N ] , nxt [ N ] , to [ N ] , cn ;
18 int headx [ N ] , nxtx [ N ] , tox [ N ] , cnn ;
19 int dfn [ N ] , low [ N ] , belong [ N ] , cnt , cnx ;
20 int ind [ N ] , op [ N ] , color [ N ] ;
21 int sth , stm , enh , enm , len , n ;
22 bool ins [ N ] ;
23
24 int minx ( int a , int b ) {
25 return a > b ? b : a ;
26 }
27
28 void create ( int u , int v ) {
29 cn ++ ;
30 to [ cn ] = v ;
31 nxt [ cn ] = head [ u ] ;
32 head [ u ] = cn ;
33 }
34
35 void create_x ( int u , int v ) {
36 cnn ++ ;
37 tox [ cnn ] = v ;
38 nxtx [ cnn ] = headx [ u ] ;
39 headx [ u ] = cnn ;
40 }
41
42 bool conflict ( int id1 , int id2 ) {
43 int st1 = dot [ id1 ] . st , en1 = dot [ id1 ] . en ;
44 int st2 = dot [ id2 ] . st , en2 = dot [ id2 ] . en ;
45 if ( st1 >= en2 || st2 >= en1 )
46 return false ;
47 return true ;
48 }
49
50 void rebuild ( ) {
51
52 for ( int i = 1 ; i <= 2 * n ; i ++ ) {
53 int tmp1 = belong [ i ] ;
54 for ( int j = head [ i ] ; j ; j = nxt [ j ] ) {
55 int tmp2 = belong [ to [ j ] ] ;
56 if ( tmp1 != tmp2 ) {
57 create_x ( tmp2 , tmp1 ) ;
58 ind [ tmp1 ] ++ ;
59 }
60 }
61 }
62
63 }
64
65 void opp ( ) {
66 for ( int i = 1 ; i <= n ; i ++ ) {
67 op [ belong [ i ] ] = belong [ i + n ] ;
68 op [ belong [ i + n ] ] = belong [ i ] ;
69 }
70 }
71
72 bool judge () {
73 for ( int i = 1 ; i <= n ; i ++ )
74 if ( belong [ i ] == belong [ i + n ] )
75 return true ;
76 return false ;
77 }
78
79 void topsort ( ) {
80 for ( int i = 1 ; i <= cnx ; i ++ )
81 if ( ind [ i ] == 0 )
82 q . push ( i ) ;
83 while ( ! q . empty ( ) ) {
84 int tmp = q . front ( ) ;
85 q . pop ( ) ;
86 if ( color [ tmp ] == 0 )
87 color [ tmp ] = 1 , color [ op [ tmp ] ] = 2 ;
88 //if ( color [ tmp ] == 2 ) continue ;
89 for ( int i = headx [ tmp ] ; i ; i = nxtx [ i ] ) {
90 ind [ tox [ i ] ] -- ;
91 if ( ! ind [ tox [ i ] ] )
92 q . push ( tox [ i ] ) ;
93 }
94 }
95 }
96
97 void tarjan ( int x ) {
98 cnt ++ ;
99 dfn [ x ] = low [ x ] = cnt ;
100 ins [ x ] = true ; s . push ( x ) ;
101 for ( int i = head [ x ] ; i ; i = nxt [ i ] ) {
102 int v = to [ i ] ;
103 if ( ! dfn [ v ] ) {
104 tarjan ( v ) ;
105 low [ x ] = minx ( low [ x ] , low [ v ] ) ;
106 }
107 else if ( ins [ v ] ) low [ x ] = minx ( low [ x ] , dfn [ v ] ) ;
108 }
109 if ( dfn [ x ] == low [ x ] ) {
110 cnx ++ ;
111 while ( 1 ) {
112 int tmp = s . top ( ) ;
113 s . pop ( ) ;
114 ins [ tmp ] = false ;
115 belong [ tmp ] = cnx ;
116 if ( x == tmp ) break ;
117 }
118 }
119 }
120
121 int main ( ) {
122
123 while ( scanf ( "%d" , & n ) == 1 ) {
124
125 cnx = 0 ; cnt = 0 ; cn = 0 ; cnn = 0 ;
126 memset ( head , 0 , sizeof ( head ) ) ;
127 memset ( nxt , 0 , sizeof ( nxt ) ) ;
128 memset ( to , 0 , sizeof ( to ) ) ;
129 memset ( headx , 0 , sizeof ( headx ) ) ;
130 memset ( nxtx , 0 , sizeof ( nxtx ) ) ;
131 memset ( tox , 0 , sizeof ( tox ) ) ;
132 memset ( belong , 0 , sizeof ( belong ) ) ;
133 memset ( dfn , 0 , sizeof ( dfn ) ) ;
134 memset ( ins , false , sizeof ( ins ) ) ;
135 memset ( low , 0 , sizeof ( low ) ) ;
136 memset ( dot , 0 , sizeof ( dot ) ) ;
137 memset ( ind , 0 , sizeof ( ind ) ) ;
138 memset ( op , 0 , sizeof ( op ) ) ;
139 memset ( color , 0 , sizeof ( color ) ) ;
140
141 for ( int i = 1 ; i <= n ; i ++ ) {
142 scanf ( "%d:%d %d:%d %d" , & sth , & stm , & enh , & enm , & len ) ;
143 dot [ i ] . st = sth * 60 + stm ;
144 dot [ i ] . en = sth * 60 + stm + len ;
145 dot [ i + n ] . st = enh * 60 + enm - len ;
146 dot [ i + n ] . en = enh * 60 + enm ;
147 }
148
149 for ( int i = 1 ; i <= n ; i ++ )
150 for ( int j = 1 ; j <= n ; j ++ )
151 if ( i != j ) {
152 if ( conflict ( i , j ) ) {
153 create ( i , j + n ) ;
154 create ( j , i + n ) ;
155 }
156 if ( conflict ( i , j + n ) ) {
157 create ( i , j ) ;
158 create ( j + n , i + n ) ;
159 }
160 if ( conflict ( i + n , j ) ) {
161 create ( i + n , j + n ) ;
162 create ( j , i ) ;
163 }
164 if ( conflict ( i + n , j + n ) ) {
165 create ( i + n , j ) ;
166 create ( j + n , i ) ;
167 }
168 }
169
170 for ( int i = 1 ; i <= 2 * n ; i ++ )
171 if ( ! dfn [ i ] )
172 tarjan ( i ) ;
173
174 if ( judge ( ) ) {
175 printf ( "NO\n" ) ;
176 continue ;
177 }
178 else printf ( "YES\n" ) ;
179
180 rebuild ( ) ;
181
182 opp ( ) ;
183
184 topsort ( ) ;
185
186 for ( int i = 1 ; i <= n ; i ++ )
187 if ( color [ belong [ i ] ] == 1 )
188 printf ( "%.2d:%.2d %.2d:%.2d\n" , dot [ i ] . st / 60 , dot [ i ] . st % 60 , dot [ i ] . en / 60 , dot [ i ] . en % 60 ) ;
189 else
190 printf ( "%.2d:%.2d %.2d:%.2d\n" , dot [ i + n ] . st / 60 , dot [ i + n ] . st % 60 , dot [ i + n ] . en / 60 , dot [ i + n ] . en % 60 ) ;
191 }
192
193 return 0 ;
194 }
下面是AC代码
1 #include <cstdio>
2 #include <stack>
3 #include <queue>
4 #include <cstring>
5
6 const int N = 4000 + 5 ;
7
8 std :: stack < int > s ;
9 std :: queue < int > q ;
10 std :: vector < int > g [ N ] , rg [ N ] ;
11
12 struct ConfirmedHY {
13 int st ;
14 int en ;
15 }
16 dot [ N ] ;
17
18 int dfn [ N ] , low [ N ] , belong [ N ] , cnt , cnx ;
19 int ind [ N ] , op [ N ] , color [ N ] ;
20 int sth , stm , enh , enm , len , n ;
21 bool ins [ N ] ;
22
23 int minx ( int a , int b ) {
24 return a > b ? b : a ;
25 }
26
27 void create ( int u , int v ) {
28 g [ u ] . push_back ( v ) ;
29 }
30
31 void create_x ( int u , int v ) {
32 rg [ u ] . push_back ( v ) ;
33 }
34
35 bool conflict ( int id1 , int id2 ) {
36 int st1 = dot [ id1 ] . st , en1 = dot [ id1 ] . en ;
37 int st2 = dot [ id2 ] . st , en2 = dot [ id2 ] . en ;
38 if ( st1 >= en2 || st2 >= en1 )
39 return false ;
40 return true ;
41 }
42
43 void rebuild ( ) {
44
45 for ( int i = 1 ; i <= 2 * n ; i ++ ) {
46 int tmp1 = belong [ i ] ;
47 for ( int j = 0 ; j < g [ i ] . size ( ) ; j ++ ) {
48 int tmp2 = belong [ g [ i ] [ j ] ] ;
49 if ( tmp1 != tmp2 ) {
50 create_x ( tmp2 , tmp1 ) ;
51 ind [ tmp1 ] ++ ;
52 }
53 }
54 }
55
56 }
57
58 void opp ( ) {
59 for ( int i = 1 ; i <= n ; i ++ ) {
60 op [ belong [ i ] ] = belong [ i + n ] ;
61 op [ belong [ i + n ] ] = belong [ i ] ;
62 }
63 }
64
65 bool judge () {
66 for ( int i = 1 ; i <= n ; i ++ )
67 if ( belong [ i ] == belong [ i + n ] )
68 return true ;
69 return false ;
70 }
71
72 void topsort ( ) {
73 for ( int i = 1 ; i <= cnx ; i ++ )
74 if ( ind [ i ] == 0 )
75 q . push ( i ) ;
76 while ( ! q . empty ( ) ) {
77 int tmp = q . front ( ) ;
78 q . pop ( ) ;
79 if ( color [ tmp ] == 0 )
80 color [ tmp ] = 1 , color [ op [ tmp ] ] = 2 ;
81 //if ( color [ tmp ] == 2 ) continue ;
82 for ( int i = 0 ; i < rg [ tmp ] . size ( ) ; i ++ ) {
83 int v = rg [ tmp ] [ i ] ;
84 ind [ v ] -- ;
85 if ( ! ind [ v ] )
86 q . push ( v ) ;
87 }
88 }
89 }
90
91 void tarjan ( int x ) {
92 cnt ++ ;
93 dfn [ x ] = low [ x ] = cnt ;
94 ins [ x ] = true ; s . push ( x ) ;
95 for ( int i = 0 ; i < g [ x ] . size ( ) ; i ++ ) {
96 int v = g [ x ] [ i ] ;
97 if ( ! dfn [ v ] ) {
98 tarjan ( v ) ;
99 low [ x ] = minx ( low [ x ] , low [ v ] ) ;
100 }
101 else if ( ins [ v ] ) low [ x ] = minx ( low [ x ] , dfn [ v ] ) ;
102 }
103 if ( dfn [ x ] == low [ x ] ) {
104 cnx ++ ;
105 while ( 1 ) {
106 int tmp = s . top ( ) ;
107 s . pop ( ) ;
108 ins [ tmp ] = false ;
109 belong [ tmp ] = cnx ;
110 if ( x == tmp ) break ;
111 }
112 }
113 }
114
115 int main ( ) {
116
117 while ( scanf ( "%d" , & n ) == 1 ) {
118
119 cnx = 0 ; cnt = 0 ;
120 memset ( belong , 0 , sizeof ( belong ) ) ;
121 memset ( dfn , 0 , sizeof ( dfn ) ) ;
122 memset ( ins , false , sizeof ( ins ) ) ;
123 memset ( low , 0 , sizeof ( low ) ) ;
124 memset ( dot , 0 , sizeof ( dot ) ) ;
125 memset ( ind , 0 , sizeof ( ind ) ) ;
126 memset ( op , 0 , sizeof ( op ) ) ;
127 memset ( color , 0 , sizeof ( color ) ) ;
128
129 for ( int i = 1 ; i <= n ; i ++ ) {
130 scanf ( "%d:%d %d:%d %d" , & sth , & stm , & enh , & enm , & len ) ;
131 dot [ i ] . st = sth * 60 + stm ;
132 dot [ i ] . en = sth * 60 + stm + len ;
133 dot [ i + n ] . st = enh * 60 + enm - len ;
134 dot [ i + n ] . en = enh * 60 + enm ;
135 }
136
137 for ( int i = 1 ; i <= n ; i ++ )
138 for ( int j = 1 ; j <= n ; j ++ )
139 if ( i != j ) {
140 if ( conflict ( i , j ) ) {
141 create ( i , j + n ) ;
142 create ( j , i + n ) ;
143 }
144 if ( conflict ( i , j + n ) ) {
145 create ( i , j ) ;
146 create ( j + n , i + n ) ;
147 }
148 if ( conflict ( i + n , j ) ) {
149 create ( i + n , j + n ) ;
150 create ( j , i ) ;
151 }
152 if ( conflict ( i + n , j + n ) ) {
153 create ( i + n , j ) ;
154 create ( j + n , i ) ;
155 }
156 }
157
158 for ( int i = 1 ; i <= 2 * n ; i ++ )
159 if ( ! dfn [ i ] )
160 tarjan ( i ) ;
161
162 if ( judge ( ) ) {
163 printf ( "NO\n" ) ;
164 continue ;
165 }
166 else printf ( "YES\n" ) ;
167
168 rebuild ( ) ;
169
170 opp ( ) ;
171
172 topsort ( ) ;
173
174 for ( int i = 1 ; i <= n ; i ++ )
175 if ( color [ belong [ i ] ] == 1 )
176 printf ( "%.2d:%.2d %.2d:%.2d\n" , dot [ i ] . st / 60 , dot [ i ] . st % 60 , dot [ i ] . en / 60 , dot [ i ] . en % 60 ) ;
177 else
178 printf ( "%.2d:%.2d %.2d:%.2d\n" , dot [ i + n ] . st / 60 , dot [ i + n ] . st % 60 , dot [ i + n ] . en / 60 , dot [ i + n ] . en % 60 ) ;
179
180 for ( int i = 1 ; i <= 2 * n ; i ++ ) {
181 g [ i ] . clear ( ) ;
182 rg [ i ] . clear ( ) ;
183 }
184 }
185
186 return 0 ;
187 }
以上是关于POJ 3683 Priest John's Busiest Day 2-Sat的主要内容,如果未能解决你的问题,请参考以下文章
POJ 3683 Priest John's Busiest Day(2-sat)
POJ 3683.Priest John's Busiest Day 2-SAT
POJ - 3683 Priest John's Busiest Day
POJ 3683 Priest John's Busiest Day(2-SAT)