思路
在有向图中点与点能互相到达。即求从点1出发的强连通分量是否包含所有点。
low[]更新回溯最短的时间点,dfn[]到达的时间点。深度搜索,遇到访问过的点表明可以构成这段路径强连通分量,更新low。当low[to]>dfn[now]时,说明now不在含有to的强连通分量里,即这个图里含有不止一个强连通分量。
实现
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e5+5;
int n,m;
vector<pair<int,int> > edge[100005];
int low[maxn],dfn[maxn],t;
vector<pair<int,int> > ans;
bool vis[maxn],f = 0;
void targin(int now){
dfn[now]=low[now]=++t;
for(auto i:edge[now]){
int to = i.first,id = i.second;
if (f) return;
if (vis[id]) continue;
vis[id] = 1;
ans.push_back(make_pair(now,to));
if (!dfn[to]){
targin(to);
low[now] = min(low[now],low[to]);
}else{
//不用low[to]为了避免割点,不过这题有割点没影响
low[now] = min(low[now],dfn[to]);
}
if (low[to]>dfn[now]) return void (f = 1);
}
}
void solve(){
cin>>n>>m;
for(int i=1,a,b;i<=m;i++){
cin>>a>>b;
edge[a].push_back(make_pair(b,i));
edge[b].push_back(make_pair(a,i));
}
targin(1);
if (f) {cout<<0<<endl;return;}
for(int i=0;i<m;i++)
cout<<ans[i].first<<" "<<ans[i].second<<endl;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
solve();
}
感悟
好烦,图的连通性要回顾下了(割点,桥,强连通分量)。
话说链式前向星的搜索速度比邻接表快好多。。
不过这问题倒也挺典型的。
文章讲述了如何在有向图中检测从点1出发的强连通分量是否包含所有点,使用low和dfn数组进行深度优先搜索,同时提到图的连通性概念及相关数据结构(如割点、桥和链式前向星)的应用。

401

被折叠的 条评论
为什么被折叠?



