【POI2008] BLO-封鎖
タイトル説明
Byteotiaで正確nnは町があります。
いくつかの町は、双方向の道路で接続されています。
橋、トンネルや高架道路があるかもしれませんが外町は、何の岐路にありません。町の各ペアは、最大で1本の直接的な道路で接続することができます。一つは、他の-直接的または間接的に任意の町から得ることができます。
各町は、1つの市民を持っています。
そのため市民が孤独に苦しみます。
これは、市民一人ひとりが、(彼のホストの故郷で)他のすべての市民への訪問を支払う、と一度だけ、それをやりたいということが判明しました。だから、ちょうどn \ CDOT(N-1)n⋅(n-1)の訪問は行われるべきです。
これは、右必要があります。
残念ながら、ソフトウェアの緊急購入を要求プログラマのゼネストは、進行中です。
抗議の行為として、プログラマはそれを残して、それを入力防止、Byteotiaの1つの町をブロックすることを計画し、さらに通過します。
我々が話すと、彼らはとても影響が最も深刻であることを選択するためにどの町議論されています。
タスクは、そのプログラムを書きます:
各町は決定のために、標準入力からByteotian道路システムの説明を読み、この町は、プログラマによってブロックされなかった場合は場所を取ることができるか、多くの訪問、標準出力に結果を書き出します。
無向グラフが与えられると、要求後の各点はxの(X!= Y、1 <= X、Y <= n)の点(x、y)の順序付けられた数のブロックされており、yは到達できません
入力形式
標準入力の最初の行に2つの正の整数であり:NNとMM(1 \ルN \ル100 \0001≤n≤100000、1 \ルM \ル\0001≤m≤500000 500)表します町や道路の数、それぞれ。
町は、NNに1から番号が付けられています。
次ミリメートルラインは、道路の説明が含まれています。
各行は二つの整数AAとBBが含まれています(1 \ルA <\ルn1≤a<b≤nB)と町の番号AAとBBの間の直接の道を示しています。
最初の行が読み取らN、M、町の数と道路の数でありさ
出力フォーマット
あなたのプログラムは、標準出力に1行に1つずつ番号を正確にnnは整数を書き出す必要があります。I ^ {}番目のI
番目の
行は、プログラマが町なしにブロックされた場合は場所を取ることができなかった訪問数を含める必要があります。II。
城镇编号1〜n個
次の2行各m番号、Bは、AとBとの間の無向エッジを表明しています
場合、i番目のロック町N本の出力線、各ディジット線、アクセス回数が発生することができません。
刃先と同等のものを得ながら、得られたTarjanカット点、このエッジを計算するために後方に記録すべきサブツリーの数です。
点が各カット点について決定された場合、刃先は、各カット点について決定された複数の接続があり、各寸法は、サブツリーの数です。
その後、サイズを計算するために少し数学を使用することができます。
難易度:サブツリーサイズの各接続点の切断刃先の統計を考えることがより困難であり、数式が良いプッシュあります。
コード:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=100010;
const int M=1000100;
const LL mod=100000000;
int dfn[N],low[N],tot,head[N],cnt,n,m,vis[N];
vector<LL>ve[N];
struct Node{
int to,nex;
}edge[M];
void add(int p,int q){
edge[cnt].to=q;
edge[cnt].nex=head[p];
head[p]=cnt++;
}
int Tarjan(int p,int fa){
dfn[p]=low[p]=++tot;
int ch=0;//儿子数量
int sum1=1,sum2=1;
for(int i=head[p];~i;i=edge[i].nex){
int q=edge[i].to;
if(!dfn[q]){
ch++;
int s=Tarjan(q,p);
sum1+=s;
low[p]=min(low[p],low[q]);
if(p!=fa&&low[q]>=dfn[p]){
sum2+=s;
ve[p].push_back(1ll*s);
vis[p]=1;
}
if(p==fa&&ch>=2){
sum2+=s;
ve[p].push_back(1ll*s);
vis[p]=1;
}
}
else if(q!=fa) low[p]=min(low[p],dfn[q]);
}
ve[p].push_back(1ll*(n-sum2));
return sum1;
}
int main(){
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
Tarjan(1,1);
for(int i=1;i<=n;i++){
if(vis[i]){
LL ans=0;
for(int j=0;j<ve[i].size();j++){
ans+=(1ll*n-ve[i][j])*ve[i][j];
}
ans+=1ll*(n-1);
printf("%lld\n",ans);
}
else printf("%lld\n",2ll*(n-1));
}
return 0;
}