您的位置:首页 > 其它

poj 3683 Priest John's Busiest Day

2017-09-02 16:14 337 查看
题目链接:http://poj.org/problem?id=3683

用强连通分量求解的2SAT问题。

SAT定义





题解



Can you hear me ? 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

typedef long long ll ;
const int MAX_V = 10005 ;
int V ; // point
vector <int> G[MAX_V] ;
vector <int> rG[MAX_V] ;
vector <int> vs ;
bool used[MAX_V] ;
int cmp[MAX_V] ;// tuo pu pai xu jie guo

void add_edge( int from , int to ){
G[from].push_back(to) ;
rG[to].push_back(from) ;
}
void dfs( int v ){
used[v] = true ;
for( int i = 0 ; i < G[v].size() ; i ++ ){
if( !used[ G[v][i] ]) dfs( G[v][i] ) ;
}
vs.push_back(v) ;
}
void rdfs( int v , int k ){
used[v] = true ;
cmp[v] = k ;
for( int i = 0 ; i < rG[v].size() ; i ++ ){
if( ! used[rG[v][i] ]) rdfs( rG[v][i] , k );
}
}
int scc(){
memset(used , 0 ,sizeof( used)) ;
vs.clear() ;
for( int v = 1 ; v <= V ; v ++ ){
if( !used[v]) dfs(v) ;
}
memset( used , 0 ,sizeof( used )) ;
int k = 0 ;
for( int i = vs.size() - 1 ; i >= 0 ; i -- ){
if( ! used[ vs[i] ]) rdfs( vs[i] , k ++ ) ;
}
return k ;
}
int S[MAX_V] , T[MAX_V] , D[MAX_V] , n ;
void solve(){
for( int i = 1 ; i <= n ; i ++ ){
for( int j = 1 ; j < i ; j ++ ){
if( min( S[i]+D[i] , S[j]+D[j]) > max(S[i] , S[j])){
add_edge( i , n + j ) ;
add_edge( j , n + i ) ;
}
if( min(S[i]+D[i] , T[j]) > max( S[i] , T[j]-D[j])){
add_edge( i , j ) ;
add_edge( n+j , n+i) ;
}
if( min(T[i] , S[j]+D[j]) > max(T[i]-D[i] , S[j]) ){
add_edge( j , i ) ;
add_edge( n+i , n+j) ;
}
if( min(T[i] , T[j]) > max(T[i]-D[i] , T[j]-D[j])){
add_edge(n+i , j);
add_edge(n+j , i ) ;
}
}
}
scc() ;
for( int i = 1 ; i <= n ; i ++ ){
if(cmp[i] == cmp[n+i]){
cout << "NO" << endl ;
return ;
}
}
cout << "YES" << endl ;
for( int i = 1 ; i <= n ; i ++ ){
if( cmp[i] > cmp[n+i]){
printf("%02d:%02d %02d:%02d\n" , S[i]/60 , S[i]%60 , (S[i]+D[i])/60 , (S[i]+D[i])%60) ;
}else{
printf("%02d:%02d %02d:%02d\n" , (T[i]-D[i])/60 , (T[i]-D[i])%60 , (T[i])/60 , (T[i])%60) ;
}
}

}
int main()
{
int m , a , b , c , d , e ;
while( cin >> n )
{
V = n * 2 ; ///

for( int i = 0 ; i <= n ; i ++ ) {
G[i].clear() , rG[i].clear() ;
}memset(cmp , 0 , sizeof( cmp)) ;
for( int i = 1 ; i <= n ; i ++ ){
scanf("%d:%d %d:%d %d",&a,&b,&c,&d,&e) ;
S[i] = a*60+b , T[i] = c*60 + d ;
D[i] = e ;
}

//int ans = scc() ;
solve() ;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: