//因为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;
}
tarjan算法-双连通分量
最新推荐文章于 2024-08-02 19:17:54 发布