您的位置:首页 > 其它

HDU 6165 FFF at Valentine

2017-08-22 18:15 344 查看
题意:

给定一个有向图,n个点,m条边,无自环,无重边

问:是否任意两点A,B,满足AB连通

规模:

2<=n<=1000,m<=6000

T<120

类型:

有向强连通,拓扑排序

分析:

有向图缩环后,拓扑排序一下,如果入度为0的点有多个,就无法连通

代码:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1010;
const int MAXM=6010;
struct Edge{
int to,next;
}edge[MAXM],edge2[MAXM];
int head[MAXN],head2[MAXN],tot,tot2;
int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];
int Index,top;
int scc;
bool Instack[MAXN];
int num[MAXN];
int in[MAXN],out[MAXN];
void addedge(int u,int v){
edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;
}
void addedge2(int u,int v){
edge2[tot2].to=v;edge2[tot2].next=head2[u];head2[u]=tot2++;
}
void Tarjan(int u){
int v;
Low[u]=DFN[u]=++Index;
Stack[top++]=u;
Instack[u]=true;
for(int i=head[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(!DFN[v]){
Tarjan(v);
if(Low[u]>Low[v])Low[u]=Low[v];
}
else if(Instack[v]&&Low[u]>DFN[v])
Low[u]=DFN[v];
}
if(Low[u]==DFN[u]){
scc++;
do{
v=Stack[--top];
Instack[v]=false;
Belong[v]=scc;
num[scc]++;
}
while(v!=u);
}
}
void solve(int N){
memset(DFN,0,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
memset(num,0,sizeof(num));
Index=scc=top=0;
for(int i=1;i<=N;i++){
if(!DFN[i])
Tarjan(i);
}
}

bool map2[MAXN][MAXN];
void build(int n){
memset(map2,false,sizeof(map2));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(head2,-1,sizeof(head2));tot2=0;
for(int i=1;i<=n;i++){
for(int j=head[i];j!=-1;j=edge[j].next){
int v=edge[j].to;
int a=Belong[i];
int b=Belong[v];
if(a==b)continue;
if(!map2[a][b]){
addedge2(a,b);
map2[a][b]=true;
in[b]++;out[a]++;
}
}
}
}

void init(){
tot=0;
memset(head,-1,sizeof(head));
}

bool Top(){
queue<int >q;
while(!q.empty())q.pop();
for(int i=1;i<=scc;i++){
if(in[i]==0)q.push(i);
}

while(!q.empty()){
if(q.size()!=1)return false;
int u=q.front();
q.pop();
for(int i=1;i<=scc;i++){
if(map2[u][i]==true) {
in[i]--;
if(in[i]==0)q.push(i);
}
}
}
return true;
}

int n,m;
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
init();
for(int i=0;i<m;i++){
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
}
solve(n);
build(n);

if(!Top()){printf("Light my fire!\n");}
else printf("I love you my love and our love save us!\n");
}

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