Codeforces goodbye 2014

来源:互联网 发布:八宝茶的软件 编辑:程序博客网 时间:2024/05/01 06:36

D题 

对每条边考虑

边的两侧分别有x,y个节点,所以经过该边的种数为x*y*(n-2) 

x,y可dfs求出

(n-2) 为第三个点选取的位置

接下来就是乘乘减减了 

#include <cstdio>#include <cstdlib>#include <cmath>#include <set>#include <stack>#include <vector>#include <sstream>#include <cstring>#include <string>#include <map>#include <queue>#include <algorithm>#include <iostream>#define FFI freopen("in.txt", "r", stdin)#define maxn 100010#define INF 0x3f3f3f3f#define inf 10000000#define MOD 1000000007#define ULL unsigned long long#define LL long long#define _setm(houge) memset(houge, INF, sizeof(houge))#define _setf(houge) memset(houge, -1, sizeof(houge))#define _clear(houge) memset(houge, 0, sizeof(houge))using namespace std;int n, m;int a[maxn], b[maxn], len[maxn], cnt[maxn];vector<int> g[maxn];int dfs(int u, int fa) {    cnt[u] = 1;    for(int i = 0; i < (int)g[u].size(); ++ i) {        if(g[u][i] == fa) continue;        dfs(g[u][i], u);        cnt[u] += cnt[g[u][i]];    }    return cnt[u];}int main(){    while(scanf("%d", &n) == 1) {        for(int i = 0; i < n; ++ i) g[i].clear();        for(int i = 0; i < n-1; ++ i) {            scanf("%d%d%d", &a[i], &b[i], &len[i]);            a[i] --;            b[i] --;            g[a[i]].push_back(b[i]);            g[b[i]].push_back(a[i]);        }        dfs(0, -1);        double C[maxn];        for(int i = 0; i < n-1; ++ i) {            long long v = min(cnt[a[i]], cnt[b[i]]);            C[i] = (double)v*(n-v)*(n-2);        }        double res = 0;        for(int i = 0; i < n-1; ++ i) {            res += C[i]*len[i];        }        double x = (double)n*(n-1)*(n-2)/6;        scanf("%d", &m);        for(int i = 0; i < m; ++ i) {            int r, w;            scanf("%d%d", &r, &w);            r --;            res -= C[r]*(len[r]-w);            len[r] = w;            printf("%.10lf\n", res/x);        }    }    return 0;}


0 0
原创粉丝点击