D e s c r i p t i o n Description Description
求必须经过某个点的最近点对数量
5 × n ≤ 1 0 4 , m ≤ 1 0 5 5\times n\leq 10^4,m\leq 10^5 5×n≤104,m≤105
S o l u t i o n Solution Solution
T a r j a n Tarjan Tarjan割点求点双
C o d e Code Code
#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
using namespace std;int n,m,x,y,ans[50001],t,dfn[50001],low[50001],subtree[50001],f[50001];
vector<int>to[50001];
bool vis[50001];
inline char Getchar()
{
static char buf[10000000],*p1=buf+10000000,*pend=buf+10000000;
if(p1==pend)
{
p1=buf; pend=buf+fread(buf,1,10000000,stdin);
if (pend==p1) return -1;
}
return *p1++;
}
inline long long read()
{
char c;int d=1;long long f=0;
while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void Tarjan(int x)
{
vis[x]=true;subtree[x]=1;
dfn[x]=++t;low[x]=t;
int s=0;
for(register int i=0;i<to[x].size();i++)
{
int y=to[x][i];
if(vis[y]) low[x]=min(low[x],dfn[y]);
else
{
f[y]=x;
Tarjan(y);
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x])
{
ans[x]+=(n-subtree[y]-1)*subtree[y];
s+=subtree[y];
}
subtree[x]+=subtree[y];
}
}
ans[x]+=(n-s-1)*s;
return;
}
signed main()
{
n=read();m=read();
for(register int i=1;i<=m;i++)
{
x=read();y=read();
to[x].push_back(y);to[y].push_back(x);
}
Tarjan(1);
for(register int i=1;i<=n;i++) printf("%d\n",ans[i]/2+n-1);
}