tarjan算法-双连通分量

//因为long long wa了几发....然后主要就是注意割点和求联通分量条件不一样,求割点的条件并不需要low[num]==dfn[num]这个条件太严格了。只需要low[to]<=dfn[num]即可
//无向图的点连通分量什么的和有向图差不多,细节yy一下即可。
//发现一个奇怪的现象为什么内存开的越大时间越短呢????
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct edgee
{
	int to;
};
int first[100005], nextt[1000006];
edgee edge[1000006];
int edgetot = 1;
long long size[1000005], ans[100005];
int low[100005], dfn[100005];
int dfstot=1;
int n, m;
void addedgee(int a, int b)
{
	edge[edgetot].to = b;
	nextt[edgetot] = first[a];
	first[a] = edgetot;
	edgetot++;
	edge[edgetot].to = a;
	nextt[edgetot] = first[b];
	first[b] = edgetot;
	edgetot++;
}
void tarjan(int num)
{
	low[num] = dfn[num] = dfstot++;
	size[num] = 1;
	long long t = 0;
	for (int i = first[num]; i; i = nextt[i])
	{
		int to = edge[i].to;
		if (dfn[to] == 0)
		{
			tarjan(to);
			low[num] = min(low[num], low[to]);
			size[num] += size[to];
			if (low[to] >= dfn[num])
			{
				ans[num] += t*size[to];
				t += size[to];
			}
		}
		else
			low[num] = min(low[num], dfn[to]);//这不需要任何条件也就是不用管横向边为什么自己yy
	}
		ans[num] += (n - t - 1)*t;
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		addedgee(a, b);
	}
	tarjan(1);
	for (int i = 1; i <= n; i++)
	{
		ans[i] = (ans[i] + n - 1) * 2;
		printf("%lld\n", ans[i]);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值