这是一道裸的2-Sat,只要考虑矛盾条件的判断就好了。
矛盾判断:
对于婚礼现场 x 和 y,x 的第一段可以和 y 的第一段或者第二段矛盾,同理,x 的第二段可以和 y 的第一段或者第二段矛盾,条件是 x 的 1或2 段与 y 的 1或2 段有重合,那么选了 x 某一段就不能选择其矛盾的那一段,那就只能选择 y 中的另一段,建立一条 x (u)-> y ( v的对立 ),同理,x (u的对立)<- y ( v ) 。
代码是:
for ( int i = 1 ; i <= n ; i ++ )
for ( int j = 1 ; j <= n ; j ++ )
if ( i != j ) {
if ( conflict ( i , j ) ) {
create ( i , j + n ) ;
create ( j , i + n ) ;
}
if ( conflict ( i , j + n ) ) {
create ( i , j ) ;
create ( j + n , i + n ) ;
}
if ( conflict ( i + n , j ) ) {
create ( i + n , j + n ) ;
create ( j , i ) ;
}
if ( conflict ( i + n , j + n ) ) {
create ( i + n , j ) ;
create ( j + n , i ) ;
}
}
真的,2-sat千万不要用邻接链表!!!卡死卡死卡死!!!稠密图!!!不要用!!!
我WA和RE和MLE都怪邻接链表!!!!!!!!!!!!!!!!!!!!!!!!!
总代码:
下面第一个代码纪念邻接链表这个垃圾的Failure!
#include <cstdio>
#include <stack>
#include <queue>
#include <cstring>
const int N = 2000000 + 5 ;
std :: stack < int > s ;
std :: queue < int > q ;
struct ConfirmedHY {
int st ;
int en ;
}
dot [ N ] ;
int head [ N ] , nxt [ N ] , to [ N ] , cn ;
int headx [ N ] , nxtx [ N ] , tox [ N ] , cnn ;
int dfn [ N ] , low [ N ] , belong [ N ] , cnt , cnx ;
int ind [ N ] , op [ N ] , color [ N ] ;
int sth , stm , enh , enm , len , n ;
bool ins [ N ] ;
int minx ( int a , int b ) {
return a > b ? b : a ;
}
void create ( int u , int v ) {
cn ++ ;
to [ cn ] = v ;
nxt [ cn ] = head [ u ] ;
head [ u ] = cn ;
}
void create_x ( int u , int v ) {
cnn ++ ;
tox [ cnn ] = v ;
nxtx [ cnn ] = headx [ u ] ;
headx [ u ] = cnn ;
}
bool conflict ( int id1 , int id2 ) {
int st1 = dot [ id1 ] . st , en1 = dot [ id1 ] . en ;
int st2 = dot [ id2 ] . st , en2 = dot [ id2 ] . en ;
if ( st1 >= en2 || st2 >= en1 )
return false ;
return true ;
}
void rebuild ( ) {
for ( int i = 1 ; i <= 2 * n ; i ++ ) {
int tmp1 = belong [ i ] ;
for ( int j = head [ i ] ; j ; j = nxt [ j ] ) {
int tmp2 = belong [ to [ j ] ] ;
if ( tmp1 != tmp2 ) {
create_x ( tmp2 , tmp1 ) ;
ind [ tmp1 ] ++ ;
}
}
}
}
void opp ( ) {
for ( int i = 1 ; i <= n ; i ++ ) {
op [ belong [ i ] ] = belong [ i + n ] ;
op [ belong [ i + n ] ] = belong [ i ] ;
}
}
bool judge () {
for ( int i = 1 ; i <= n ; i ++ )
if ( belong [ i ] == belong [ i + n ] )
return true ;
return false ;
}
void topsort ( ) {
for ( int i = 1 ; i <= cnx ; i ++ )
if ( ind [ i ] == 0 )
q . push ( i ) ;
while ( ! q . empty ( ) ) {
int tmp = q . front ( ) ;
q . pop ( ) ;
if ( color [ tmp ] == 0 )
color [ tmp ] = 1 , color [ op [ tmp ] ] = 2 ;
//if ( color [ tmp ] == 2 ) continue ;
for ( int i = headx [ tmp ] ; i ; i = nxtx [ i ] ) {
ind [ tox [ i ] ] -- ;
if ( ! ind [ tox [ i ] ] )
q . push ( tox [ i ] ) ;
}
}
}
void tarjan ( int x ) {
cnt ++ ;
dfn [ x ] = low [ x ] = cnt ;
ins [ x ] = true ; s . push ( x ) ;
for ( int i = head [ x ] ; i ; i = nxt [ i ] ) {
int v = to [ i ] ;
if ( ! dfn [ v ] ) {
tarjan ( v ) ;
low [ x ] = minx ( low [ x ] , low [ v ] ) ;
}
else if ( ins [ v ] ) low [ x ] = minx ( low [ x ] , dfn [ v ] ) ;
}
if ( dfn [ x ] == low [ x ] ) {
cnx ++ ;
while ( 1 ) {
int tmp = s . top ( ) ;
s . pop ( ) ;
ins [ tmp ] = false ;
belong [ tmp ] = cnx ;
if ( x == tmp ) break ;
}
}
}
int main ( ) {
while ( scanf ( "%d" , & n ) == 1 ) {
cnx = 0 ; cnt = 0 ; cn = 0 ; cnn = 0 ;
memset ( head , 0 , sizeof ( head ) ) ;
memset ( nxt , 0 , sizeof ( nxt ) ) ;
memset ( to , 0 , sizeof ( to ) ) ;
memset ( headx , 0 , sizeof ( headx ) ) ;
memset ( nxtx , 0 , sizeof ( nxtx ) ) ;
memset ( tox , 0 , sizeof ( tox ) ) ;
memset ( belong , 0 , sizeof ( belong ) ) ;
memset ( dfn , 0 , sizeof ( dfn ) ) ;
memset ( ins , false , sizeof ( ins ) ) ;
memset ( low , 0 , sizeof ( low ) ) ;
memset ( dot , 0 , sizeof ( dot ) ) ;
memset ( ind , 0 , sizeof ( ind ) ) ;
memset ( op , 0 , sizeof ( op ) ) ;
memset ( color , 0 , sizeof ( color ) ) ;
for ( int i = 1 ; i <= n ; i ++ ) {
scanf ( "%d:%d %d:%d %d" , & sth , & stm , & enh , & enm , & len ) ;
dot [ i ] . st = sth * 60 + stm ;
dot [ i ] . en = sth * 60 + stm + len ;
dot [ i + n ] . st = enh * 60 + enm - len ;
dot [ i + n ] . en = enh * 60 + enm ;
}
for ( int i = 1 ; i <= n ; i ++ )
for ( int j = 1 ; j <= n ; j ++ )
if ( i != j ) {
if ( conflict ( i , j ) ) {
create ( i , j + n ) ;
create ( j , i + n ) ;
}
if ( conflict ( i , j + n ) ) {
create ( i , j ) ;
create ( j + n , i + n ) ;
}
if ( conflict ( i + n , j ) ) {
create ( i + n , j + n ) ;
create ( j , i ) ;
}
if ( conflict ( i + n , j + n ) ) {
create ( i + n , j ) ;
create ( j + n , i ) ;
}
}
for ( int i = 1 ; i <= 2 * n ; i ++ )
if ( ! dfn [ i ] )
tarjan ( i ) ;
if ( judge ( ) ) {
printf ( "NO\n" ) ;
continue ;
}
else printf ( "YES\n" ) ;
rebuild ( ) ;
opp ( ) ;
topsort ( ) ;
for ( int i = 1 ; i <= n ; i ++ )
if ( color [ belong [ i ] ] == 1 )
printf ( "%.2d:%.2d %.2d:%.2d\n" , dot [ i ] . st / 60 , dot [ i ] . st % 60 , dot [ i ] . en / 60 , dot [ i ] . en % 60 ) ;
else
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 ) ;
}
return 0 ;
}
下面是AC代码
#include <cstdio>
#include <stack>
#include <queue>
#include <cstring>
const int N = 4000 + 5 ;
std :: stack < int > s ;
std :: queue < int > q ;
std :: vector < int > g [ N ] , rg [ N ] ;
struct ConfirmedHY {
int st ;
int en ;
}
dot [ N ] ;
int dfn [ N ] , low [ N ] , belong [ N ] , cnt , cnx ;
int ind [ N ] , op [ N ] , color [ N ] ;
int sth , stm , enh , enm , len , n ;
bool ins [ N ] ;
int minx ( int a , int b ) {
return a > b ? b : a ;
}
void create ( int u , int v ) {
g [ u ] . push_back ( v ) ;
}
void create_x ( int u , int v ) {
rg [ u ] . push_back ( v ) ;
}
bool conflict ( int id1 , int id2 ) {
int st1 = dot [ id1 ] . st , en1 = dot [ id1 ] . en ;
int st2 = dot [ id2 ] . st , en2 = dot [ id2 ] . en ;
if ( st1 >= en2 || st2 >= en1 )
return false ;
return true ;
}
void rebuild ( ) {
for ( int i = 1 ; i <= 2 * n ; i ++ ) {
int tmp1 = belong [ i ] ;
for ( int j = 0 ; j < g [ i ] . size ( ) ; j ++ ) {
int tmp2 = belong [ g [ i ] [ j ] ] ;
if ( tmp1 != tmp2 ) {
create_x ( tmp2 , tmp1 ) ;
ind [ tmp1 ] ++ ;
}
}
}
}
void opp ( ) {
for ( int i = 1 ; i <= n ; i ++ ) {
op [ belong [ i ] ] = belong [ i + n ] ;
op [ belong [ i + n ] ] = belong [ i ] ;
}
}
bool judge () {
for ( int i = 1 ; i <= n ; i ++ )
if ( belong [ i ] == belong [ i + n ] )
return true ;
return false ;
}
void topsort ( ) {
for ( int i = 1 ; i <= cnx ; i ++ )
if ( ind [ i ] == 0 )
q . push ( i ) ;
while ( ! q . empty ( ) ) {
int tmp = q . front ( ) ;
q . pop ( ) ;
if ( color [ tmp ] == 0 )
color [ tmp ] = 1 , color [ op [ tmp ] ] = 2 ;
//if ( color [ tmp ] == 2 ) continue ;
for ( int i = 0 ; i < rg [ tmp ] . size ( ) ; i ++ ) {
int v = rg [ tmp ] [ i ] ;
ind [ v ] -- ;
if ( ! ind [ v ] )
q . push ( v ) ;
}
}
}
void tarjan ( int x ) {
cnt ++ ;
dfn [ x ] = low [ x ] = cnt ;
ins [ x ] = true ; s . push ( x ) ;
for ( int i = 0 ; i < g [ x ] . size ( ) ; i ++ ) {
int v = g [ x ] [ i ] ;
if ( ! dfn [ v ] ) {
tarjan ( v ) ;
low [ x ] = minx ( low [ x ] , low [ v ] ) ;
}
else if ( ins [ v ] ) low [ x ] = minx ( low [ x ] , dfn [ v ] ) ;
}
if ( dfn [ x ] == low [ x ] ) {
cnx ++ ;
while ( 1 ) {
int tmp = s . top ( ) ;
s . pop ( ) ;
ins [ tmp ] = false ;
belong [ tmp ] = cnx ;
if ( x == tmp ) break ;
}
}
}
int main ( ) {
while ( scanf ( "%d" , & n ) == 1 ) {
cnx = 0 ; cnt = 0 ;
memset ( belong , 0 , sizeof ( belong ) ) ;
memset ( dfn , 0 , sizeof ( dfn ) ) ;
memset ( ins , false , sizeof ( ins ) ) ;
memset ( low , 0 , sizeof ( low ) ) ;
memset ( dot , 0 , sizeof ( dot ) ) ;
memset ( ind , 0 , sizeof ( ind ) ) ;
memset ( op , 0 , sizeof ( op ) ) ;
memset ( color , 0 , sizeof ( color ) ) ;
for ( int i = 1 ; i <= n ; i ++ ) {
scanf ( "%d:%d %d:%d %d" , & sth , & stm , & enh , & enm , & len ) ;
dot [ i ] . st = sth * 60 + stm ;
dot [ i ] . en = sth * 60 + stm + len ;
dot [ i + n ] . st = enh * 60 + enm - len ;
dot [ i + n ] . en = enh * 60 + enm ;
}
for ( int i = 1 ; i <= n ; i ++ )
for ( int j = 1 ; j <= n ; j ++ )
if ( i != j ) {
if ( conflict ( i , j ) ) {
create ( i , j + n ) ;
create ( j , i + n ) ;
}
if ( conflict ( i , j + n ) ) {
create ( i , j ) ;
create ( j + n , i + n ) ;
}
if ( conflict ( i + n , j ) ) {
create ( i + n , j + n ) ;
create ( j , i ) ;
}
if ( conflict ( i + n , j + n ) ) {
create ( i + n , j ) ;
create ( j + n , i ) ;
}
}
for ( int i = 1 ; i <= 2 * n ; i ++ )
if ( ! dfn [ i ] )
tarjan ( i ) ;
if ( judge ( ) ) {
printf ( "NO\n" ) ;
continue ;
}
else printf ( "YES\n" ) ;
rebuild ( ) ;
opp ( ) ;
topsort ( ) ;
for ( int i = 1 ; i <= n ; i ++ )
if ( color [ belong [ i ] ] == 1 )
printf ( "%.2d:%.2d %.2d:%.2d\n" , dot [ i ] . st / 60 , dot [ i ] . st % 60 , dot [ i ] . en / 60 , dot [ i ] . en % 60 ) ;
else
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 ) ;
for ( int i = 1 ; i <= 2 * n ; i ++ ) {
g [ i ] . clear ( ) ;
rg [ i ] . clear ( ) ;
}
}
return 0 ;
}