zoukankan      html  css  js  c++  java
  • Codeforces 1060E(思维+贡献法)

    https://codeforces.com/contest/1060/problem/E

    题意

    给一颗树,在原始的图中假如两个点连向同一个点,这两个点之间就可以连一条边,定义两点之间的长度为两点之间的最少边数,求加边之后任意两点长度之和

    思路

    • 一看到求任意两点,知道需要用每条边的贡献计算(每条边使用了多少次)

      每条边的贡献等于边左边的点数*边右边的点数

    • 然后就一直不知道怎么解决加边后的问题,不知道要标记哪些东西,怎么减去
    • 单独看一条路径,加边之后,
      • 假如边数是偶数的话,边数/2
      • 假如边数是奇数的话,必定会走过一条跨过二分图的边
    • 所以只需要把连接二分图的边加上再除以2就得出答案了
    #include<bits/stdc++.h>
    #define M 200005
    #define pb push_back
    #define ll long long
    using namespace std;
    vector<int>g[M];
    ll f[M],son[M];
    int n,i,u,v;
    ll ans;
    
    void dfs(int u,int fa,int st){
        son[u]=1;f[st]++;
        for(int i=0;i<g[u].size();i++){
            int v=g[u][i];if(fa==v)continue;
            dfs(v,u,st^1);
            son[u]+=son[v];
        }
        ans+=son[u]*(n-son[u]);
    }
    int main(){
        cin>>n;
        for(i=0;i<n-1;i++){scanf("%d%d",&u,&v);g[u].pb(v);g[v].pb(u);}
        dfs(1,0,0);
        cout<<(ans+f[0]*f[1])/2;
    }
    
  • 相关阅读:
    PLSQL游标
    SqlHelper助手
    机房重构前奏——三层转七层
    应用运筹管理经济
    C++——宏观把控
    操作系统——宏观把控
    .NET总结一
    深复制与浅复制
    设计模式之结构型
    设计模式之一对多
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/9986780.html
Copyright © 2011-2022 走看看