CSES-1682 Flight Routes Check
作者:互联网
Flight Routes Check
判断是不是一个强连通图,如果不是,就找出不能到达的单程
tarjan 模板
判断不能到达的,直接从 \(1\) 开始走一次搜索,如果与 \(1\) 不同强连通块上的点,且 \(1\) 能够到达那个点,显然答案就是从那个点到 \(1\)
记得考虑整个图不连通的情况
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1e5 + 10;
vector<int>gra[maxn];
int dfn[maxn], low[maxn], tp = 0;
int vis[maxn], st[maxn], stp = 0;
int cnt_scc = 0, scc[maxn];
void tarjan(int now)
{
dfn[now] = ++tp;
low[now] = dfn[now];
vis[now] = 1;
st[++stp] = now;
for(int nex : gra[now])
{
if(dfn[nex] == 0)
{
tarjan(nex);
low[now] = min(low[now], low[nex]);
}
else if(vis[nex])
low[now] = min(low[now], low[nex]);
}
if(low[now] == dfn[now])
{
cnt_scc++;
while(st[stp] != now)
{
int x = st[stp--];
vis[x] = 0;
scc[x] = cnt_scc;
}
scc[now] = cnt_scc;
vis[now] = 0;
st[stp--] = 0;
}
}
void dfs(int now)
{
if(vis[now]) return;
vis[now] = 1;
for(int nex : gra[now])
dfs(nex);
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for(int i=0; i<m; i++)
{
int a, b;
scanf("%d%d", &a, &b);
gra[a].push_back(b);
}
for(int i=1; i<=n; i++)
if(dfn[i] == 0) tarjan(i);
if(cnt_scc == 1) printf("YES\n");
else
{
int x = 0;
for(int i=1; i<=n && x == 0; i++)
if(scc[1] != scc[i]) x = i;
int u = 1, v = x;
dfs(1);
if(vis[v]) swap(u, v);
printf("NO\n%d %d\n", u, v);
}
return 0;
}
标签:Flight,int,vis,1682,maxn,low,nex,Routes,now 来源: https://www.cnblogs.com/dgsvygd/p/16579650.html