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 5Sample Output
8 8 16 14 8居然被题面坑了……不能连通的点对是有序点对,而且自己删了要算自己不能和别人连……
无向图tarjan用点双,求出哪些点是割点,然后就是自己的所有子树大小相乘,还有父亲的那一块区域。最后要加上n-1,有序的话再乘个2就好
/*program from Wolfycz*/#include#include #include #include #include #define inf 0x7f7f7f7fusing namespace std;typedef long long ll;typedef unsigned int ui;typedef unsigned long long ull;inline int read(){ int x=0,f=1;char ch=getchar(); for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0'; return x*f;}inline void print(int x){ if (x>=10) print(x/10); putchar(x%10+'0');}const int N=1e5,M=5e5;int pre[(M<<1)+10],now[N+10],child[(M<<1)+10];int dfn[N+10],low[N+10],size[N+10];ll Ans[N+10];int Time,n,m,tot;void join(int x,int y){pre[++tot]=now[x],now[x]=tot,child[tot]=y;}void tarjan(int x){ int T=0; size[x]=1; dfn[x]=low[x]=++Time; for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){ if (!dfn[son]){ tarjan(son); size[x]+=size[son]; low[x]=min(low[x],low[son]); if (dfn[x]<=low[son]){ Ans[x]+=1ll*T*size[son]; T+=size[son]; } }else low[x]=min(low[x],dfn[son]); } Ans[x]+=1ll*T*(n-T-1);}int main(){ n=read(),m=read(); for (int i=1;i<=m;i++){ int x=read(),y=read(); join(x,y),join(y,x); } tarjan(1); for (int i=1;i<=n;i++) printf("%lld\n",(Ans[i]+n-1)<<1); return 0;}