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
#include<cstdio> int hea[100010],nxt[1000010],to[1000010],dfn[100010],low[100010],siz[100010],tot,num,n,m; long long ans[100010]; void add(int a,int b) { nxt[++tot]=hea[a]; hea[a]=tot; to[tot]=b; } void tarjan(int x,int rt) { dfn[x]=low[x]=++num; siz[x]=1; int f=0,cut=0,s=0; for(int i=hea[x];i;i=nxt[i]) { int y=to[i]; if(!dfn[y]) { tarjan(y,rt); siz[x]+=siz[y]; low[x]=low[x]<low[y]?low[x]:low[y]; if(low[y]>=dfn[x]) { f++; if(f>1||x!=rt)cut=1; ans[x]=ans[x]+1ll*(n-siz[y])*siz[y]; //x是个割点,去掉它后 //它下面的子树Y中所有点,与图中其它点都不连通 s+=siz[y]; } } else low[x]=low[x]<dfn[y]?low[x]:dfn[y]; } if(cut) ans[x]=ans[x]+1ll*(n-s-1)*(s+1)+n-1; //(n-s-1)代表去掉割点及它下面那些子树结点后,留下来的点 //这些点与这(s+1)个点不连通 //最后那个n-1是指x点本身与其它的所有点不连通 else //如果x不是割点,则去掉它所有的边,它只与其它N-1个点不连通 ans[x]=2*n-2; } int main() { int x,y; scanf("%d%d",&n,&m); for(int i=1;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 ",ans[i]); return 0; }