[POI2008]BLO
Time Limit: 10 Sec Memory Limit: 162 MB
Description
Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通。
Input
输入n<=100000 m<=500000及m条边
Output
输出n个数,代表如果把第i个点去掉,将有多少对点不能互通。
Sample Input
5 5
1 2
2 3
1 3
3 4
4 5
Sample Output
8
8
16
14
8
<br >
<br >
<br >
<br >
<br >
这可能是个割点吧。。。。网上的博客写的都特别好。。。
大概就是简单计数
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
struct lpl{
int fa, size, low, dfn;
}node[maxn];
vector<int> point[maxn];
int n, m, cnt, root = 1, llppdd;
long long ans[maxn];
bool flag[maxn];
inline void putit()
{
int u, v;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; ++i){
scanf("%d%d", &u, &v);
point[u].push_back(v); point[v].push_back(u);
}
}
void dfs(int t)
{
node[t].dfn = node[t].low = ++cnt;
node[t].size = 1; llppdd = point[t].size() - 1;
long long lin = 0;
for(int i = point[t].size() - 1; i >= 0; --i){
int now = point[t][i];
if(node[now].dfn) node[t].low = min(node[t].low, node[now].dfn);
else{
node[now].fa = t; dfs(now);
node[t].size += node[now].size; node[t].low = min(node[t].low, node[now].low);
if(node[t].dfn <= node[now].low){
ans[t] += (long long)lin * node[now].size;
lin += node[now].size;
}
}
}
ans[t] += (long long)lin * (n - 1 - lin);
}
int main()
{
putit();
dfs(root);
for(int i = 1; i <= n; ++i) printf("%lld
", (ans[i] + n - 1) * 2);
return 0;
}