tarjan算法-双连通分量

来源:互联网 发布:密钥算法 加密算法 编辑:程序博客网 时间:2024/05/17 02:59
//因为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];}}elselow[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;}

原创粉丝点击