POJ-3683-Priest John's Busiest Day(2-SAT染色)
2017-05-02 21:18
627 查看
链接:http://poj.org/problem?id=3683
2-SAT求其中一个解,详见2-SAT解法浅析
//#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <string>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 2010
#define MAXM 2000010
int ind,head[MAXN];
int low[MAXN],DFN[MAXN],belong[MAXN],top,stack_[MAXN],in_stack[MAXN],deep,cir;
struct node
{
int v,next;
} edge[MAXM];
struct no
{
int st,ed;
} S[MAXN],T[MAXN];
void add_(int u, int v)
{
edge[ind].v=v;
edge[ind].next=head[u];
head[u]=ind++;
}
void Tarjan(int u)
{
DFN[u]=low[u]=++deep;
in_stack[u]=1;
stack_[top++]=u;
for(int i=head[u]; i+1; i=edge[i].next)
{
int v=edge[i].v;
if(!DFN[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(in_stack[v])
low[u]=min(DFN[v],low[u]);
}
int p;
if(low[u]==DFN[u])
{
cir++;
do
{
p=stack_[--top];
in_stack[p]=0;
belong[p]=cir;
}
while(p!=u);
}
}
bool inv(no x,no y)
{
if(x.ed<=y.st || y.ed<=x.st)return 0;
return 1;
}
vector<int> mp[MAXN];
int in_[MAXN],clr[MAXN],fir[MAXN];
int main()
{
int m,n;
while(scanf("%d",&n)!=EOF)
{
ind=deep=top=cir=0;
memset(clr,-1,sizeof(clr));
memset(in_,0,sizeof(in_));
memset(head,-1,sizeof(head));
memset(DFN,0,sizeof(DFN));
memset(in_stack,0,sizeof(in_stack));
for(int i=0; i<=n; ++i)mp[i].clear();
int a,b,c,d,e,f,g;
int cnt=0;
for(int i=0; i<n; ++i)
{
scanf("%d:%d %d:%d %d", &a,&b,&c,&d,&e);
S[cnt].st=a*60+b;
S[cnt].ed=S[cnt].st+e;
cnt++;
S[cnt].ed=c*60+d;
S[cnt].st=S[cnt].ed-e;
cnt++;
for(int j=0; j<i; ++j)
{
if(inv(S[i<<1],S[j<<1]))add_(i<<1,j<<1^1);
if(inv(S[i<<1],S[j<<1^1]))add_(i<<1,j<<1);
if(inv(S[i<<1^1],S[j<<1]))add_(i<<1^1,j<<1^1);
if(inv(S[i<<1^1],S[j<<1^1]))add_(i<<1^1,j<<1);
if(inv(S[j<<1],S[i<<1]))add_(j<<1,i<<1^1);
if(inv(S[j<<1],S[i<<1^1]))add_(j<<1,i<<1);
if(inv(S[j<<1^1],S[i<<1]))add_(j<<1^1,i<<1^1);
if(inv(S[j<<1^1],S[i<<1^1]))add_(j<<1^1,i<<1);
}
}
for(int i=0; i<(n<<1); ++i)
if(!DFN[i])Tarjan(i);
int flag=0;
for(int i=0; i<n; ++i)
{
if(belong[i<<1]==belong[i<<1^1])
{
flag=1;break;
}
fir[ belong[i<<1] ]=belong[i<<1^1];
fir[ belong[i<<1^1] ]=belong[i<<1];
}
if(flag)
{
printf("NO\n");
continue;
}
for(int i=0; i<(n<<1); ++i)
{
for(int j=head[i]; j+1; j=edge[j].next)
{
int v=edge[j].v;
if(belong[v]!=belong[i])
{
in_[ belong[i] ]++;
mp[ belong[v] ].push_back( belong[i] );
}
}
}
queue<int> q;
for(int i=1; i<=cir; ++i)
if(!in_[i])q.push(i);
while(!q.empty())
{
int u=q.front();
q.pop();
if(clr[u]==-1)
{
clr[u]=1;
clr[fir[u]]=0;
}
int siz=mp[u].size();
for(int i=0; i<siz; ++i)
{
in_[ mp[u][i] ]--;
if(!in_[ mp[u][i] ])q.push(mp[u][i]);
}
}
printf("YES\n");
for(int i=0; i<(n<<1); i+=2)
{
if(clr[belong[i]]==1)
{
a=S[i].st/60;
b=S[i].st%60;
c=S[i].ed/60;
d=S[i].ed%60;
printf("%02d:%02d %02d:%02d\n",a,b,c,d);
}
else
{
a=S[i^1].st/60;
b=S[i^1].st%60;
c=S[i^1].ed/60;
d=S[i^1].ed%60;
printf("%02d:%02d %02d:%02d\n",a,b,c,d);
}
}
}
return 0;
}
/*
2
08:00 09:00 30
08:15 09:00 20
*/
2-SAT求其中一个解,详见2-SAT解法浅析
//#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <string>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 2010
#define MAXM 2000010
int ind,head[MAXN];
int low[MAXN],DFN[MAXN],belong[MAXN],top,stack_[MAXN],in_stack[MAXN],deep,cir;
struct node
{
int v,next;
} edge[MAXM];
struct no
{
int st,ed;
} S[MAXN],T[MAXN];
void add_(int u, int v)
{
edge[ind].v=v;
edge[ind].next=head[u];
head[u]=ind++;
}
void Tarjan(int u)
{
DFN[u]=low[u]=++deep;
in_stack[u]=1;
stack_[top++]=u;
for(int i=head[u]; i+1; i=edge[i].next)
{
int v=edge[i].v;
if(!DFN[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(in_stack[v])
low[u]=min(DFN[v],low[u]);
}
int p;
if(low[u]==DFN[u])
{
cir++;
do
{
p=stack_[--top];
in_stack[p]=0;
belong[p]=cir;
}
while(p!=u);
}
}
bool inv(no x,no y)
{
if(x.ed<=y.st || y.ed<=x.st)return 0;
return 1;
}
vector<int> mp[MAXN];
int in_[MAXN],clr[MAXN],fir[MAXN];
int main()
{
int m,n;
while(scanf("%d",&n)!=EOF)
{
ind=deep=top=cir=0;
memset(clr,-1,sizeof(clr));
memset(in_,0,sizeof(in_));
memset(head,-1,sizeof(head));
memset(DFN,0,sizeof(DFN));
memset(in_stack,0,sizeof(in_stack));
for(int i=0; i<=n; ++i)mp[i].clear();
int a,b,c,d,e,f,g;
int cnt=0;
for(int i=0; i<n; ++i)
{
scanf("%d:%d %d:%d %d", &a,&b,&c,&d,&e);
S[cnt].st=a*60+b;
S[cnt].ed=S[cnt].st+e;
cnt++;
S[cnt].ed=c*60+d;
S[cnt].st=S[cnt].ed-e;
cnt++;
for(int j=0; j<i; ++j)
{
if(inv(S[i<<1],S[j<<1]))add_(i<<1,j<<1^1);
if(inv(S[i<<1],S[j<<1^1]))add_(i<<1,j<<1);
if(inv(S[i<<1^1],S[j<<1]))add_(i<<1^1,j<<1^1);
if(inv(S[i<<1^1],S[j<<1^1]))add_(i<<1^1,j<<1);
if(inv(S[j<<1],S[i<<1]))add_(j<<1,i<<1^1);
if(inv(S[j<<1],S[i<<1^1]))add_(j<<1,i<<1);
if(inv(S[j<<1^1],S[i<<1]))add_(j<<1^1,i<<1^1);
if(inv(S[j<<1^1],S[i<<1^1]))add_(j<<1^1,i<<1);
}
}
for(int i=0; i<(n<<1); ++i)
if(!DFN[i])Tarjan(i);
int flag=0;
for(int i=0; i<n; ++i)
{
if(belong[i<<1]==belong[i<<1^1])
{
flag=1;break;
}
fir[ belong[i<<1] ]=belong[i<<1^1];
fir[ belong[i<<1^1] ]=belong[i<<1];
}
if(flag)
{
printf("NO\n");
continue;
}
for(int i=0; i<(n<<1); ++i)
{
for(int j=head[i]; j+1; j=edge[j].next)
{
int v=edge[j].v;
if(belong[v]!=belong[i])
{
in_[ belong[i] ]++;
mp[ belong[v] ].push_back( belong[i] );
}
}
}
queue<int> q;
for(int i=1; i<=cir; ++i)
if(!in_[i])q.push(i);
while(!q.empty())
{
int u=q.front();
q.pop();
if(clr[u]==-1)
{
clr[u]=1;
clr[fir[u]]=0;
}
int siz=mp[u].size();
for(int i=0; i<siz; ++i)
{
in_[ mp[u][i] ]--;
if(!in_[ mp[u][i] ])q.push(mp[u][i]);
}
}
printf("YES\n");
for(int i=0; i<(n<<1); i+=2)
{
if(clr[belong[i]]==1)
{
a=S[i].st/60;
b=S[i].st%60;
c=S[i].ed/60;
d=S[i].ed%60;
printf("%02d:%02d %02d:%02d\n",a,b,c,d);
}
else
{
a=S[i^1].st/60;
b=S[i^1].st%60;
c=S[i^1].ed/60;
d=S[i^1].ed%60;
printf("%02d:%02d %02d:%02d\n",a,b,c,d);
}
}
}
return 0;
}
/*
2
08:00 09:00 30
08:15 09:00 20
*/
相关文章推荐
- POJ 3683 Priest John's Busiest Day (2-SAT)
- poj - 3683 - Priest John's Busiest Day(2-SAT)
- |poj 3683|2-SAT|Priest John's Busiest Day
- POJ 3683 Priest John's Busiest Day (2-SAT)
- Priest John's Busiest Day poj 3683 tarjan+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 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(2—sat)
- [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输出任意一组解
- [2-SAT 任意解 Tarjan 模板题] POJ 3683 Priest John's Busiest Day
- POJ 3683. Priest John's Busiest Day
- POJ 3683 Priest John's Busiest Day
- POJ 3683 Priest John's Busiest Day 笔记
- POJ 3683 John's Busiest Day(2-SAT)
- POJ 3683 Priest John's Busiest Day