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】

原文地址:https://www.cnblogs.com/horsepower2001/p/8975092.html

时间: 2024-10-06 03:31:12

POJ 3683 Priest John's Busiest Day 【2-Sat】的相关文章

POJ 3683 Priest John&#39;s Busiest Day(2-SAT)

[题目链接] http://poj.org/problem?id=3683 [题目大意] 每个婚礼有两个时段可以进行特别仪式,特别仪式必须要有神父在场, 神父只有一个,问是否能满足所有婚礼的需求, [题解] 因为两个时段必须要满足一个时段,所以如果一个时段被占用那么另一个时段必须被空出来, 我们根据各个婚礼两个时段之间的冲突关系建边,之后跑2-SAT,判断是否冲突, 若无冲突则输出方案. [代码] #include <cstdio> #include <algorithm> #in

POJ 3683 Priest John&#39;s Busiest Day (2-SAT+输出可行解)

题目地址:POJ 3683 第一次做需要输出可行解的题目...大体思路是先用强连通来判断是否有可行解,然后用逆序建图,用拓扑排序来进行染色,然后输出可行解.具体思路见传送门 因为判断的时候少写了一个等号..检查了好长时间..sad... 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #incl

POJ 3683(Priest John&#39;s Busiest Day-强连通分量解决2-SAT)[Template:2-SAT]

Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8144   Accepted: 2769   Special Judge Description John is the only priest in his town. September 1st is the John's busiest day in a year because there is an old le

POJ 3683.Priest John&#39;s Busiest Day 2-SAT

Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10144   Accepted: 3472   Special Judge Description John is the only priest in his town. September 1st is the John's busiest day in a year because there is an old l

POJ 3683 Priest John&#39;s Busiest Day(2-SAT+方案输出)

Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10010   Accepted: 3425   Special Judge Description John is the only priest in his town. September 1st is the John's busiest day in a year because there is an old l

POJ 3684 Priest John&#39;s Busiest Day 2-SAT+输出路径

强连通算法判断是否满足2-sat,然后反向建图,拓扑排序+染色. 一种选择是从 起点开始,另一种是终点-持续时间那个点 开始. 若2个婚礼的某2种时间线段相交,则有矛盾,建边. 容易出错的地方就在于判断线段相交. 若s1<e2&&s2<e1则相交 输出路径的做法可以参考论文2-SAT解法浅析 #include <iostream> #include<cstring> #include<cstdio> #include<string>

HDU2491 Priest John&#39;s Busiest Day

题目链接 题意: 有n个人要进行乒乓球比赛,每个人都一个能力值,每个人出现的次序就是他们住的位置 现在要求进行一场比赛,三个人,裁判的能力值在两个选手之间,住的位置也在两个人的之间 问这种比赛一共可以进行多少次 思路: 用树状数组做,否则TLE,先从左到右扫一遍,计算每点左边大的个数和小的个数, 再从右到左扫一遍,计算每点右边大和小的个数,然后交叉相乘取和就可以了 代码如下: #include<cstdio> #include<cstring> #include<string

UVA - 1420 Priest John&#39;s Busiest Day

题目大意:有一个司仪,要主持 n 场婚礼,给出婚礼的起始时间和终止时间,每个婚礼需要超过一半的时间做为仪式,并且仪式不能终止.问说司仪能否主持 n 场婚礼. 解题思路:贪心,为了尽量主持多的婚礼,每场的仪式时间就一定要尽量短 d = (t - s) / 2 + 1,(因为必须大于一半,所以加 1).然后按照每场婚礼可以最晚结束的时间排序 t - d,(因为要满足所有的婚礼,所以尽量解决早点的仪式,腾出时间来给后面的婚礼),维护一个占用时间值即可. #include <cstdio> #incl

POJ-3683 Priest John&#39;s Busiest Day

图论中的2-SAT.模板题. #include <cstdio> #include <cstdlib> #include <algorithm> #include <cctype> #include <cstring> #include <iostream> using namespace std; #define rep(i, l, r) for(int i=l; i<=r; i++) #define travel(x) fo