BLO(bzoj1123)

Description

Byteotia城市有n个 towns, m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通。

Input

输入n和m。( n<=100000 ,m<=500000 )

Output

输出n个数,其中第i个整数表示把与节点i关联的所有边去掉之后(不去掉节点i本身),无向图中有多少个有序点对(x,y),满足x和y不连通。

Sample Input

5 5
1 2
2 3
1 3
3 4
4 5

Sample Output

8
8
16
14
8

限制与约定

时间限制:1s

空间限制:128MB

std:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#define LL long long
using namespace std;
const int maxn=1e5+5;
const int maxm=5e5+5;
inline int read()
{
    int a=0;bool b=1;char x=getchar();
    while(x<'0'||'9'<x){
    if(x=='-')b=0;
    x=getchar();
    }
    while('0'<=x&&x<='9'){
    a=(a<<1)+(a<<3)+x-'0';
    x=getchar();
    }
    return b?a:-a;
}
int first[maxn],next[maxm*2],to[maxm*2],edge_count;
inline void add(int x,int y){
    edge_count++;
    to[edge_count]=y;
    next[edge_count]=first[x];
    first[x]=edge_count;
}
int pre[maxn],low[maxn],root,Time;
LL ans[maxn],size[maxn];
int n,m;
void tarjan(int u){
    pre[u]=low[u]=++Time;
    size[u]=1;
    
    int temp=0;
    long long cnt=n-1;
    for(int i=first[u];i;i=next[i]){
        int v=to[i];
        if(pre[v]){
            low[u]=min(low[u],pre[v]);
        }
        else{
            tarjan(v);
            low[u]=min(low[u],low[v]);
            size[u]+=size[v];
            
            if(pre[u]<=low[v]){
                temp++;
                if(u!=root || temp>1){
                ans[u]+=size[v]*(n-size[v]-1);
                cnt-=size[v];
                }
            }
        }
    }
    ans[u]+=cnt*(n-cnt-1);
}
int main()
{
    n=read();m=read();
    const LL N=n+n-2;
    for(int i=1,x,y;i<=m;i++){
        x=read();y=read();
        add(x,y);add(y,x); 
    }
    for(int i=1;i<=n;i++){
        if(pre[i])continue;
        root=i;
        tarjan(i);
    }
    for(int i=1;i<=n;i++){
    printf("%lld\n",ans[i]+N);
    }
     return 0;
}

奇葩问题汇总{

1.数据范围为>maxint,故要开long long 

2.其中不影响结果的变量cnt如果开int也会影响结果,

因为每一步都要考虑强制转换的问题!!!特别要注意,否则会傻逼!!!

3.因为是双向点对,所以不用复杂的记录当前已经分理出多少点->res[u]

直接乘就行还会变快,!!!而且类似的求单向点对也可以求完双向再/2即可,

排列组合很重要!!!

}

posted @ 2019-04-25 21:08  Tj1  阅读(925)  评论(0编辑  收藏  举报