1 2 3 4

割点的板子题

https://ac.nowcoder.com/acm/problem/51265

割点的板子

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;

const int maxn = 1e5 + 11;
vector<int>G[maxn];
void add(int x, int y) {
	G[x].push_back(y);
}
int low[maxn], dfn[maxn], df;
ll siz[maxn], ans[maxn];
int cnt[maxn];
int n, m;

int tarjan(int x,int root) {
	low[x] = dfn[x] = ++df;
	int flag = 0;
	ll sum = 0;
	siz[x] = 1;
	for (int i = 0; i < G[x].size(); i++) {
		int p = G[x][i];
		if (!dfn[p]) {
			tarjan(p,root);
			siz[x] += siz[p];
			low[x] = min(low[x], low[p]);

			if (low[p] >= dfn[x]) {
				flag++;
				ans[x] += 1LL * (siz[p])*(1LL * n - siz[p]);
				sum += siz[p];

				if (flag > 1 || x != root) cnt[x] = 1;
			}
		}
		else {
			low[x] = min(low[x], dfn[p]);
		}
	}
	if (cnt[x]) {
		ans[x] += 1LL * (sum + 1)*(n - sum - 1) + n - 1;
	}
	else {
		ans[x] = 2 * (n - 1);
	}
	return 0;
}


int main() {
	scanf("%d%d", &n, &m);
	int x, y;
	for (int i = 0; i < m; i++) {
		scanf("%d%d", &x, &y);
		add(x, y);
		add(y, x);
	}
	tarjan(1, 1);
	for (int i = 1; i <=n; i++) {
		printf("%lld\n", ans[i]);
	}
	return 0;
}

  

posted @ 2020-07-11 16:44  Lesning  阅读(136)  评论(0)    收藏  举报