E. Bertown roads

文章讲述了如何在有向图中检测从点1出发的强连通分量是否包含所有点,使用low和dfn数组进行深度优先搜索,同时提到图的连通性概念及相关数据结构(如割点、桥和链式前向星)的应用。

Problem - E - Codeforces

思路

        在有向图中点与点能互相到达。即求从点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();
}

感悟

        好烦,图的连通性要回顾下了(割点,桥,强连通分量)。

        话说链式前向星的搜索速度比邻接表快好多。。

        不过这问题倒也挺典型的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cando-01

随心而动,随性而为。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值