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
Sample Output
8
8
16
14
8
唔
研究了很久 样例。
题意叙述不清
题目大意:给定N个点M条边的无向图,问删除每个点后,对于有序数对(x,y)满足x,y互不连通的数对数。其中,被删掉的点也应被统计。
显然和割点有关。
如果删掉的点不是割点 ,那对别的点没有影响,只和和他有关的 n-1个点有关。
如果删掉的点是割点,那就是需要稍许改动的 tarjan。
统计一下每个块的siz,至于求割点本应考虑的 节点数量也会被考虑进去,因为不是当前t=0,就是(n-t-1)=0;
在Tarjan中如果搜到的点的low[v]< deep[u]说明没法形成强连通分量就要在ans[u]中加上每两块的size的乘积
但是确定u是割点了以后,它deep比它深的连通块和deep比它浅的不连通,所以ans[u]+=c*(n-c-1)
所以 我靠 统计数目 好懵逼啊!!
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
//by mars_ch
int n,m;
struct data{
int f,t,nxt;
}e[1000005];
int first[100005],tot,tim;
int siz[100005],low[100005],dfn[100005];
int ans[1000005];
void add(int x,int y)
{
e[tot].t=y,e[tot].nxt=first[x],first[x]=tot++;
}
void tarjan(int x)
{
int tmp=0;
dfn[x]=low[x]=++tim;
siz[x]=1;
for(int i=first[x];i!=-1;i=e[i].nxt)
{
int t=e[i].t;
if(!dfn[t])
{
tarjan(t);
siz[x]+=siz[t];
low[x]=min(low[x],low[t]);
if(low[t]>=dfn[x])
{
ans[x]+=tmp*siz[t];
tmp+=siz[t];
}
}
else low[x]=min(low[x],dfn[t]);
}
ans[x]+=tmp*(n-tmp-1);
}
signed main()
{
scanf("%lld%lld",&n,&m);
memset(first,-1,sizeof(first));
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%lld%lld",&a,&b);
add(a,b);
add(b,a);
}
tarjan(1);
puts("");
for(int i=1;i<=n;i++)
{
printf("%lld\n",(ans[i]+n-1)*2);
}
return 0;
}