1123: [POI2008]BLO
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1301 Solved: 591
[ Submit][ Status][ Discuss]
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
1 2
2 3
1 3
3 4
4 5
Sample Output
8
8
16
14
8
8
16
14
8
HINT
Source
割点板子题.
在tarjan的时候记录一下size即可. 注意乘2.
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long dnt;
const int maxn = 100005;
dnt ans[maxn];
int n, m, num, indexx;
int low[maxn], dfn[maxn], siz[maxn], h[maxn];
struct edge{ int nxt, v;}e[1000005];
inline void add(int u, int v){
e[++num].v = v, e[num].nxt = h[u], h[u] = num;
e[++num].v = u, e[num].nxt = h[v], h[v] = num;
}
inline void dfs(int u){
siz[u] = 1;
dfn[u] = low[u] = ++indexx;
int sum = 0;
for(int i = h[u]; i; i = e[i].nxt){
int v = e[i].v;
if(dfn[v]) low[u] = min(low[u], dfn[v]);
else{
dfs(e[i].v);
siz[u] += siz[v];
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u]){
ans[u] += (dnt) sum * siz[v];
sum += siz[v];
}
}
}
ans[u] += (dnt) sum * (n - sum - 1);
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; ++i){
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
}
dfs(1);
for(int i = 1; i <= n; ++i) printf("%lld\n", (ans[i] + n - 1) * 2);
}