题意:
给出若干个节点的连接方法,询问是否对于任意两点来说,都可以有一条路路径,使得其中一个点可以到达另外一个点
思路:
对于这个图来说,如果是个强连通那必定两两互达,对于一个图来说,缩点之后,如果他是一个链必定可以满足条件,搜一下就好了.
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int MAXN =10000 ;
const int MAXM =120000 ;
using namespace std;
const int maxn=10005;
int yes;
vector<int> vec[maxn];
struct Edge
{
int to,next;
}edge[MAXM];
int head[MAXN],tot;
int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];
int Index,top;
int scc;
int vis[maxn];
const int inf=0x3f3f3f3f;
bool Instack[MAXN];
int indu[MAXN];
int save[MAXN];
void addedge(int u,int v)
{
edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;
}
void dfs(int u,int num)
{
if(num==scc)
{
yes=1;
return ;
}
for(int i=0;i<vec[u].size();i++)
{
int v=vec[u][i];
if(!vis[v])
{
vis[v]=1;
dfs(v,num+1);
vis[v]=0;
}
}
}
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];
Belong[v] = scc;
Instack[v] = false;
}
while( v!= u );
}
}
void solve(int N)
{
for(int i=1;i<=N;i++)
vec[i].clear();
memset(DFN,0,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
memset(Belong,0,sizeof(Belong));
memset(indu,0,sizeof(indu));
Index = scc = top = 0;
for(int i = 1;i <= N;i++)
if(!DFN[i])
Tarjan(i);
yes=1;
for(int u = 1;u <= N;u++)
{
for(int i = head[u];i != -1;i = edge[i].next)
{
int v = edge[i].to;
if(Belong[u] != Belong[v])
{
vec[Belong[u]].push_back(Belong[v]);
indu[Belong[v]]++;
}
}
}
int cnt=0;
for(int i=1;i<=scc;i++)
{
if(indu[i]==0)
cnt++,save[cnt]=i;
}/*
for(int i=1;i<=scc;i++)
{
printf("%d %d--\n",i,indu[i]);
}*/
// printf("cnt : %d\n",cnt);
if(cnt>1)
{
yes=0;
}
if(yes)
{
memset(vis,0,sizeof(vis));
yes=0;
vis[save[cnt]]=1;
dfs(save[cnt],1);
}
if(yes)
printf("I love you my love and our love save us!\n");
else
{
printf("Light my fire!\n");
}
/*
for(int i=1;i<=scc;i++)
{
for(int j=0;j<vec[i].size();j++)
{
printf("%d--%d\n ",i,vec[i][j]);
}
}*/
}
void init()
{
tot = 0;
memset(head,-1,sizeof(head));
}
int main()
{
int n,m;
int v;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
int u,v;
for(int i = 1;i <= m;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
}
solve(n);
}
return 0;
}