[POJ 3683] Priest John 's Busiest Day (2 - SAT + 토폴로지 정렬 출력 가능)
http://poj.org/problem?id=3683
제목 의 대의
사고의 방향
코드
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXE 4100000
#define MAXV 2100
using namespace std;
struct edge
{
int u,v,next;
}edges1[MAXE],edges2[MAXE];
int head1[MAXV],nCount1=0;
int head2[MAXV],nCount2=0;
int inDegree[MAXV];
void AddEdge1(int U,int V)
{
edges1[++nCount1].u=U;
edges1[nCount1].v=V;
edges1[nCount1].next=head1[U];
head1[U]=nCount1;
}
void AddEdge2(int U,int V)
{
inDegree[V]++;
edges2[++nCount2].u=U;
edges2[nCount2].v=V;
edges2[nCount2].next=head2[U];
head2[U]=nCount2;
}
void add(int a,int typea,int b,int typeb)
{
AddEdge1((a<<1)+typea,((b<<1)+typeb)^1);
AddEdge1(((a<<1)+typea)^1,(b<<1)+typeb);
}
int dfn[MAXV],low[MAXV],dfs_time=0;
int stack[MAXV<<1],top=0;
bool inStack[MAXV];
int belong[MAXV],scc_cnt=0;
int opp[MAXV]; //opp[i]= i
void TarjanSCC(int u)
{
dfn[u]=low[u]=++dfs_time;
stack[++top]=u;
inStack[u]=true;
for(int p=head1[u];p!=-1;p=edges1[p].next)
{
int v=edges1[p].v;
if(!dfn[v])
{
TarjanSCC(v);
low[u]=min(low[u],low[v]);
}
else if(inStack[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
scc_cnt++;
while(1)
{
int now=stack[top];
inStack[now]=false;
top--;
belong[now]=scc_cnt;
if(now==u) break;
}
}
}
int n;
int starttime[MAXV],endtime[MAXV]; //
int col[MAXV]; //col[i]= i
int q[MAXV<<1]; //
void TopoSort() //
{
memset(col,0,sizeof(col));
int h=0,t=0;
for(int i=1;i<=scc_cnt;i++) if(!inDegree[i]) q[t++]=i;
while(h<t)
{
int u=q[h++];
if(!col[u]) //u
{
col[u]=1;
col[opp[u]]=-1;
}
for(int p=head2[u];p!=-1;p=edges2[p].next)
{
int v=edges2[p].v;
inDegree[v]--;
if(!inDegree[v])
q[t++]=v;
}
}
// 1
for(int i=1;i<=n;i++)
{
if(col[belong[i*2]]==-1)
{
int sthour=starttime[2*i]/60;
int stmin=starttime[2*i]%60;
int edhour=endtime[2*i]/60;
int edmin=endtime[2*i]%60;
printf("%02d:%02d %02d:%02d
",sthour,stmin,edhour,edmin);
}
else
{
int sthour=starttime[2*i+1]/60;
int stmin=starttime[2*i+1]%60;
int edhour=endtime[2*i+1]/60;
int edmin=endtime[2*i+1]%60;
printf("%02d:%02d %02d:%02d
",sthour,stmin,edhour,edmin);
}
}
}
bool hasIntersec(int i,int j) // i j , true
{
if(starttime[i]>=endtime[j]||endtime[i]<=starttime[j]) return false;
return true;
}
int main()
{
memset(head1,-1,sizeof(head1));
memset(head2,-1,sizeof(head2));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int hour1,min1,hour2,min2,t;
scanf("%d:%d %d:%d %d",&hour1,&min1,&hour2,&min2,&t);
starttime[i*2]=hour1*60+min1;
endtime[i*2]=hour1*60+min1+t;
starttime[i*2+1]=hour2*60+min2-t;
endtime[i*2+1]=hour2*60+min2;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j) continue;
if(hasIntersec(i*2,j*2)) AddEdge1(i*2,j*2+1);
if(hasIntersec(i*2,j*2+1)) AddEdge1(i*2,j*2);
if(hasIntersec(i*2+1,j*2)) AddEdge1(i*2+1,j*2+1);
if(hasIntersec(i*2+1,j*2+1)) AddEdge1(i*2+1,j*2);
/*if(hasIntersec(i*2,j*2)) add(i,0,j,0); if(hasIntersec(i*2,j*2+1)) add(i,0,j,1); if(hasIntersec(i*2+1,j*2)) add(i,1,j,0); if(hasIntersec(i*2+1,j*2+1)) add(i,1,j,1);*/
}
for(int i=2;i<=2*n+1;i++)
if(!dfn[i])
TarjanSCC(i);
bool flag=true;
for(int i=1;i<=n;i++)
{
if(belong[i*2]==belong[i*2+1])
{
flag=false;
break;
}
opp[belong[i*2]]=belong[i*2+1];
opp[belong[i*2+1]]=belong[i*2];
}
if(flag) puts("YES");
else
{
puts("NO");
return 0;
}
for(int i=1;i<=nCount1;i++)
{
int u=edges1[i].u,v=edges1[i].v;
if(belong[u]!=belong[v])
AddEdge2(belong[u],belong[v]);
}
TopoSort();
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.