Andrew Stankevich Contest 28 - I

Problem I. Travel Agency

Input file: travel.in
Output file: travel.out
Time limit: 1 second
Memory limit: 256 megabytes
Anthony is working in the intergalaxy travel agency. He often meets the requests to find a path from one planet to another using available spaceship routes.
Unfortunately, spaceships have only limited number of routes, so passengers usually have to make connections at intermediate planets.
Anthony noticed that some planets are used as intermediate more often than other. He decided to make an investigation — for each planet A he would like to know how many pairs of distinct planets (B, C)
are there, such that any path from planet B to planet C visits planet A. Help him!

Input

The first line of the input file contains two integer numbers: n and m — the number of planets and
the number of spaceship routes, respectively (2 ≤ n ≤ 20 000, 1 ≤ m ≤ 200 000). The following m lines
describe spaceship routes. Each route is bidirectional, and is described with the numbers of planets it
connects. It is possible to get from any planet to any other.

Output

Output n integer numbers — for each planet A output the number of pairs of distinct planets such that
any path from one to another goes through A.

Example

travel.in
7 9
1 2
1 3
1 4
1 5
1 6
1 7
2 3
4 5
6 7
travel.out
18
6
6
6
6
6
6

两种思路
每次算到一个割点的时候,从 (n1)×(n2)/2 开始将这个点连接的每个双连通分量的内的点对减去
最后将剩下的连通分量的点对减去

//      whn6325689
//      Mr.Phoebe
//      http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62
#define speed std::ios::sync_with_stdio(false);

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;

#define CLR(x,y) memset(x,y,sizeof(x))
#define CPY(x,y) memcpy(x,y,sizeof(x))
#define clr(a,x,size) memset(a,x,sizeof(a[0])*(size))
#define cpy(a,x,size) memcpy(a,x,sizeof(a[0])*(size))

#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))

#define MID(x,y) (x+((y-x)>>1))
#define ls (idx<<1)
#define rs (idx<<1|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
#define root 1,1,n

template<class T>
inline bool read(T &n)
{
    T x = 0, tmp = 1;
    char c = getchar();
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == EOF) return false;
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return true;
}
template <class T>
inline void write(T n)
{
    if(n < 0)
    {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n)
    {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}
//-----------------------------------

const int MAXN=40010;
const int MAXM=400010;

struct Edge
{
    int to,next;
}e[MAXM*2];

int h[MAXN],tot;
int ans[MAXN],dfn[MAXN],low[MAXN];
int sz[MAXN];
int n,m;

void addedge(int u,int v)
{
    e[tot].to=v;
    e[tot].next=h[u];
    h[u]=tot++;
}

int cnt,pop=1,top;

void bcc(int u)
{
    dfn[u]=low[u]=pop++;
    sz[u]=1;
    ans[u]=(n-1)*(n-2)/2;
    int left=n-1,v;
    for(int i=h[u];~i;i=e[i].next)
    {
        v=e[i].to;
        if(dfn[v]==-1)
        {
            bcc(v);
            if(low[v]>=dfn[u])
            {
                left-=sz[v];
                ans[u]-=sz[v]*(sz[v]-1)/2;
            }
            sz[u]+=sz[v];
            low[u]=min(low[u],low[v]);
        }
        else
            low[u]=min(low[u],dfn[v]);
    }
    ans[u]-=left*(left-1)/2;
}

int main()
{
    CLR(h,-1);CLR(dfn,-1);
    read(n),read(m);
    for(int i=1,u,v;i<=m;i++)
    {
        read(u),read(v);
        addedge(u,v);addedge(v,u);
    }
    bcc(1);
    for(int i=1;i<=n;i++)
        write(ans[i]+n-1),putchar('\n');
    return 0;
}

另一种就是直接加
就是直接用组合数学的思想就行了…

//      whn6325689
//      Mr.Phoebe
//      http://blog.csdn.net/u013007900
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#include <functional>
#include <numeric>
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

#define eps 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LLINF 1LL<<62
#define speed std::ios::sync_with_stdio(false);

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef vector<int> vi;

#define CLR(x,y) memset(x,y,sizeof(x))
#define CPY(x,y) memcpy(x,y,sizeof(x))
#define clr(a,x,size) memset(a,x,sizeof(a[0])*(size))
#define cpy(a,x,size) memcpy(a,x,sizeof(a[0])*(size))

#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define lowbit(x) (x&(-x))

#define MID(x,y) (x+((y-x)>>1))
#define ls (idx<<1)
#define rs (idx<<1|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
#define root 1,1,n

template<class T>
inline bool read(T &n)
{
    T x = 0, tmp = 1;
    char c = getchar();
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == EOF) return false;
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return true;
}
template <class T>
inline void write(T n)
{
    if(n < 0)
    {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n)
    {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}
//-----------------------------------

const int MAXN=20010;
const int MAXM=200010;

struct Edge
{
    int to,next;
}e[MAXM*2];

int h[MAXN],tot;
int ans[MAXN],dfn[MAXN],low[MAXN];
int sz[MAXN];
int n,m;

void addedge(int u,int v)
{
    e[tot].to=v;
    e[tot].next=h[u];
    h[u]=tot++;
}

int cnt,pop=1,top;

void bcc(int u)
{
    dfn[u]=low[u]=pop++;
    sz[u]=1;
    ans[u]=0;
    int sum=0,v;
    for(int i=h[u];~i;i=e[i].next)
    {
        v=e[i].to;
        if(dfn[v]==-1)
        {
            bcc(v);
            if(low[v]>=dfn[u])
            {
                ans[u]+=sum*sz[v];
                sum+=sz[v];
            }
            sz[u]+=sz[v];
            low[u]=min(low[u],low[v]);
        }
        else
            low[u]=min(low[u],dfn[v]);
    }
    ans[u]+=(n-sum-1)*sum;
}

int main()
{
    CLR(dfn,-1);CLR(h,-1);
    read(n),read(m);
    for(int i=1,u,v;i<=m;i++)
    {
        read(u),read(v);
        addedge(u,v);addedge(v,u);
    }
    bcc(1);
    for(int i=1;i<=n;i++)
        write(ans[i]+n-1),putchar('\n');
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值