您的位置:首页 > 其它

POJ 3683 Priest John's Busiest Day

2014-08-27 20:35 351 查看
题目链接:http://poj.org/problem?id=3683

题目描述:

    有一个牧师需要给n对新婚夫妇举行婚礼,每对夫妇有两个时间段进行选择,问该牧师能否给所有的夫妇举行婚礼。

     这就属于一道比较模板的2-SAT题,可以直接用模板解即可。

    关于更多2-SAT的介绍,可以参考:

    http://blog.csdn.net/dg_programming/article/details/38875861

      http://www.cnblogs.com/kuangbin/archive/2012/10/05/2712429.html

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

const int MAXN = 1005 ;
const int MAXV = 2005 ;
int V, n ;
vector<int> G[MAXV], rG[MAXV] ;
vector<int> vs ;
int cmp[MAXV] ;
bool used[MAXV] ;
int s[MAXN], t[MAXN], d[MAXN] ; //记录读入数据

void addEdge(int from, int to){
G[from].push_back(to) ;
rG[to].push_back(from) ;
}
//正向
void dfs(int t){
used[t] = true ;
for( int i = 0; i < G[t].size(); i++ ){
if( !used[G[t][i]] ) dfs(G[t][i]) ;
}
vs.push_back(t) ;
}
//反向
void rdfs(int t, int k){
used[t] = true ;
cmp[t] = k ;
for( int i = 0; i < rG[t].size(); i++ ){
if( !used[rG[t][i]] ) rdfs(rG[t][i],k) ;
}
}
//
int scc(){
memset(used,false,sizeof(used)) ;
memset(cmp,0,sizeof(cmp)) ;
vs.clear() ;
for( int i = 0; i < V; i++ ){
if( !used[i] ) dfs(i) ;
}
memset(used,false,sizeof(used)) ;
int k = 0 ;
for( int i = vs.size()-1; i >= 0; i-- ){
if( !used[vs[i]] ) rdfs(vs[i],k++) ;
}
return k ;
}
//
void twoSAT(){
V = 2*n ;
for( int i = 0; i < V; i++ ){
G[i].clear(), rG[i].clear() ;
}
for( int i = 0; i < n; i++ ){
for( int j = 0; j < i; j++ ){
//(i+n) V (j+n),当i,j有交集的时候
if( min(s[i]+d[i],s[j]+d[j]) > max(s[i],s[j]) ){
addEdge(i,j+n) ;
addEdge(j,i+n) ;
}
if( min(t[i],t[j]) > max(t[i]-d[i],t[j]-d[j]) ){
addEdge(i+n,j) ;
addEdge(j+n,i) ;
}
if( min(s[i]+d[i],t[j]) > max(s[i],t[j]-d[j]) ){
addEdge(i,j) ;
addEdge(j+n,i+n) ;
}
if( min(t[i],s[j]+d[j]) > max(t[i]-d[i],s[j]) ){
addEdge(i+n,j+n) ;
addEdge(j,i) ;
}
}
}
scc() ;
for( int i = 0; i < n; i++ ){
if( cmp[i] == cmp[i+n] ){
puts("NO") ;
return ;
}
}
puts("YES") ;
for( int i = 0; i < n; i++ ){
//i为true
if( cmp[i] > cmp[i+n] ){
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) ;
}
}
}
//
void cal(){
char tmp[8] ;
for( int i = 0; i < n; i++ ){
scanf("%s",tmp) ;
s[i] = (tmp[0]-'0')*600 + (tmp[1]-'0')*60 + (tmp[3]-'0')*10 + (tmp[4]-'0') ;
scanf("%s",tmp) ;
t[i] = (tmp[0]-'0')*600 + (tmp[1]-'0')*60 + (tmp[3]-'0')*10 + (tmp[4]-'0') ;
scanf("%d",&d[i]) ;
}
twoSAT() ;
}
//
int main(){
// freopen("1234.in","r",stdin) ;
while( scanf("%d",&n) != EOF ){
cal() ;
}

return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  2-SAT poj 图论