1123: [POI2008]BLO
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1519 Solved: 697
[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
把有序对转化成无序对,然后跑个tarjan的求割点算法就OJBK了。
#include<bits/stdc++.h> #define ll long long const int maxn=100005; using namespace std; int hd[maxn],to[maxn*10],ne[maxn*10]; int n,m,siz[maxn],dfn[maxn],low[maxn],dc=0; ll ans[maxn]; inline int read(){ int x=0; char ch=getchar(); for(;!isdigit(ch);ch=getchar()); for(;isdigit(ch);ch=getchar()) x=x*10+ch-‘0‘; return x; } void dfs(int x){ low[x]=dfn[x]=++dc; siz[x]=1; int alr=0; for(int i=hd[x];i;i=ne[i]) if(!dfn[to[i]]){ dfs(to[i]),siz[x]+=siz[to[i]]; low[x]=min(low[x],low[to[i]]); if(low[to[i]]>=dfn[x]) ans[x]+=siz[to[i]]*(ll)alr,alr+=siz[to[i]]; } else low[x]=min(low[x],dfn[to[i]]); ans[x]+=alr*(ll)(n-alr-1); } int main(){ n=read(),m=read(); int uu,vv; for(int i=1;i<=m;i++){ uu=read(),vv=read(); to[i]=vv,ne[i]=hd[uu],hd[uu]=i; to[i+m]=uu,ne[i+m]=hd[vv],hd[vv]=i+m; } fill(ans+1,ans+n+1,n-1); dfs(1); for(int i=1;i<=n;i++) printf("%lld\n",ans[i]<<1); return 0; }