1123: [POI2008]BLO
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1083 Solved: 475
[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
统计答案 我和正常人不一样系列2333
我们考虑当所有点都联通时的答案 设每个联通块大小为$v_i$ 那么显然答案是$(sum_{v_i in V}v_i)^{2}$ 我就不展开了 大家知道里面长啥样就好
然后减去$sum_{v_i in V}v_i^{2}$ 再加上$2*(V-1)$ 就是每个点的答案
/*To The End Of The Galaxy*/ #include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<iomanip> #include<bitset> #include<stack> #include<map> #include<set> #include<cmath> #include<complex> #define debug(x) cerr<<#x<<"="<<x<<endl #define INF 0x7f7f7f7f #define llINF 0x7fffffffffffll using namespace std; typedef pair<int,int> pii; typedef long long ll; inline int init() { int now=0,ju=1;char c;bool flag=false; while(1) { c=getchar(); if(c=='-')ju=-1; else if(c>='0'&&c<='9') { now=now*10+c-'0'; flag=true; } else if(flag)return now*ju; } } inline long long llinit() { long long now=0,ju=1;char c;bool flag=false; while(1) { c=getchar(); if(c=='-')ju=-1; else if(c>='0'&&c<='9') { now=now*10+c-'0'; flag=true; } else if(flag)return now*ju; } } struct edge { int from,to,val,pre; }Edge[1000005]; int head[100005],cnt,n,m,size[100005],dfs_time,dfn[100005],low[100005]; ll ans[100005]; inline void addedge(int from,int to,int val) { ++cnt; Edge[cnt]=((edge){from,to,val,head[from]}); head[from]=cnt; } inline void tarjan(int now,int fa) { dfn[now]=low[now]=++dfs_time; int t=0; size[now]++; ans[now]=((ll)(n-1)*(n-1)); ans[now]+=(ll)2*(n-1); for(int j=head[now];j;j=Edge[j].pre) { if(!dfn[Edge[j].to]) { tarjan(Edge[j].to,now); size[now]+=size[Edge[j].to]; low[now]=min(low[now],low[Edge[j].to]); if(low[Edge[j].to]>=dfn[now]) { t+=size[Edge[j].to]; ans[now]-=((ll)size[Edge[j].to]*size[Edge[j].to]); } } else if(dfn[Edge[j].to]<dfn[now]&&Edge[j].to!=fa) { low[now]=min(low[now],dfn[Edge[j].to]); } } ans[now]-=((ll)(n-t-1)*(n-t-1)); } int main() { int u,v; n=init();m=init(); for(int i=1;i<=m;i++) { u=init();v=init(); addedge(u,v,1); addedge(v,u,1); } for(int i=1;i<=n;i++) { if(!dfn[i]) { tarjan(i,0); } } for(int i=1;i<=n;i++) { printf("%lld ",ans[i]); } return 0; }