这是一道裸的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 }
玄学MLE
下面是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 }
Vector邻矩AC
POJ 3683 Priest John's Busiest Day 【2-Sat】
原文地址:https://www.cnblogs.com/horsepower2001/p/8975092.html
时间: 2024-10-06 03:31:12