POJ 3683 Priest John's Busiest Day 2-Sat

Posted horsepower2001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3683 Priest John's Busiest Day 2-Sat相关的知识,希望对你有一定的参考价值。

这是一道裸的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的主要内容,如果未能解决你的问题,请参考以下文章

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)

POJ 3683 Priest John's Busiest Day(2-SAT+方案输出)

Poj3683:Priest John's Busiest Day