zoukankan      html  css  js  c++  java
  • 8.13集训

    上午

    考试

    下午

    改题

    第一题

    给出一颗n个点的树,从1号点出发走m步,每步一条边,最多可以经过多少点?点和边均可以重复经过,但重复的点只计算一次。

    显然,我们需要找出距离1号点最远的边,这些边都只走一次,别的边走两次

    考虑三种情况:

    • 1,m过于大,即使把整个图都跑完也用不完m
    • 2,m刚好可以跑完那个距离1号点的最长链
    • 3,m可以跑完那个链,还有剩余
    #include <bits/stdc++.h>
    #define LL long long
    #define debug
    using namespace std;
    //东方之珠 整夜未眠!
    const int N = 3e5+66;
    
    int d[N];
    
    struct node {int to, nex;}e[N<<1]; int head[N], cnt;
    
    inline void jiabian(int u, int v) {
       e[++ cnt].to = v;
       e[cnt].nex = head[u];
       head[u] = cnt;
    }
    
    inline int dfs(int x, int fa) {
       int i;
       for (i = head[x]; i; i = e[i].nex) {
          int y = e[i].to;
          if (y == fa) continue;
          d[y] = d[x] + 1;
          dfs(y, x);
       }
    }
    
    inline int thestars() {
       int i, j, k, n, m, res(0);
       cin >> n >> m;
       for (i = 1; i < n; ++ i) {
          int x, y;
          cin >> x >> y;
          jiabian(x, y);
       }
       dfs(1, 0);
       for (i = 2; i <= n; ++ i) {
          if (res < d[i]) {
             res = d[i];
          }
       }
       if (m <= res) cout << m + 1;
       else if (m >= res + 2 * (n - res - 1)) cout << n;
       else cout << res + (m - res)/2 + 1;
       return 0;
    }
    
    int youngore = thestars();
    
    signed main() {;}
    

    第二题

    给出一棵n个点的树,第i个点的权值为(a_i),现在你可以进行如下操作:

    • 1,选择一个包含1号点的连通子图,使其中所有点权值+1
    • 2,选择一个包含1号点的连通子图,使其中所有点权值-1

    求最小的操作次数,使得所有点的权值都变为0

    第一次看见我以为是关于差分的题,就像这道一样

    于是我一直在想树上差分,一直在想,一直在想,可是考完试我才发现,跟tm差分没一点关系,

    如果我没有一直往差分那里钻,或许我还能想到一些暴力的做法,

    想到差分,注定了我只能拿零分

    给出gxz的题解:

    (f[i])表示以i为根的子树需要进行-1操作的次数,则需要进行+1操作的次数为(f[i]-a[i])

    考虑一个点,不考虑自身的话,需要进行的(-1)(+1)操作都是所有子节点的最大值。

    故记(M = Max(f[son]),N = Max(f[son]-a[son])),子树至少要减(M)次,自己至少要减(N+a_i)

    得到(f[i] =Max(M, N+a[i]))

    最终答案为(f[1]+(f[1]+a[1]))

    #include <bits/stdc++.h>
    #define int long long
    #define debug
    using namespace std;
    //东方之珠 整夜未眠!
    const int N = 3e5+66;
    
    int f[N], a[N];
    
    struct node {int to, nex;}e[N<<1]; int head[N<<1], cnt;
    
    inline void add(int u, int v) {
       e[++ cnt].to = v;
       e[cnt].nex = head[u];
       head[u] = cnt;
    }
    
    inline void dfs(int x, int fa) {
       int i, M(0), N(0);
       for (i = head[x]; i; i = e[i].nex) {
          int y = e[i].to;
          if (y == fa) continue;
          dfs(y, x);
          M = max(M, f[y]);
          N = max(N, f[y] - a[y]);
       }
       f[x] = max(M, N + a[x]);
    }
    
    inline int thestars() {
       int i, j, k, n, m, res(0);
       cin >> n;
       for (i = 1; i < n; ++ i) {
          int x, y;
          cin >> x >> y;
          add(x, y);
          add(y, x);
       }
       for (i = 1; i <= n; ++ i) scanf ("%lld", &a[i]);
       dfs(1, 0);
       cout << (f[1] + f[1] - a[1]);
       fclose (stdin), fclose (stdout);
       return 0;
    }
    
    int youngore = thestars();
    
    signed main() {;}
    

    注意开LL

    第三题

    click

    给出gxz题解:

    发誓再也tm不用cin了

    #include <bits/stdc++.h>
    #define LL long long
    #define debug
    using namespace std;
    //东方之珠 整夜未眠!
    const int N = 5e5+66;
    const double eps = 1e-7;
    
    double w[N], f[N], g[N];
    
    struct node {int to, nex; double val;}e[N<<1]; int head[N<<1], cnt;
    
    inline void add(int x, int y, double z) {
       e[++ cnt].to = y;
       e[cnt].val = z;
       e[cnt].nex = head[x];
       head[x] = cnt;
    }
    
    inline void dfs1(int x, int fa) {
       int i;
       f[x] = 1 - w[x];
       for (i = head[x]; i; i = e[i].nex) {
          int y = e[i].to;
          if (y == fa) continue;
          dfs1(y, x);
          f[x] *= 1 - f[y] * e[i].val;//cong 0 tui dao 1
       }
       f[x] = 1 - f[x]; //f[x] cong biao shi 0 bian cheng le biao shi 1
    }
    
    inline void dfs2(int x, int fa) {
       int i;
       for (i = head[x]; i; i = e[i].nex) {
          int y = e[i].to;
          if (y == fa) continue;
          if (1 - f[y] * e[i].val < eps) g[y] = 1;
          else g[y] = 1 - (1 - f[y]) * (1 - (1 - (1 - g[x]) / (1 - f[y] * e[i].val)) * e[i].val);
          dfs2(y, x);
       }
    }
    
    inline int thestars() {
       int i, j, k, x, y, n;
       double z, res(0);
       cin >> n;
       for (i = 1; i < n; ++ i) {
          scanf ("%d%d%lf", &x, &y, &z);
          add(x, y, z/100);
          add(y, x, z/100);
       }
       for(i = 1 ; i <= n ; i ++ ) scanf("%lf" , &w[i]) , w[i] /= 100;
       dfs1(1, 0);
       g[1] = f[1];
       dfs2(1, 0);
       for (i = 1; i <= n; ++ i) res += g[i];
       printf ("%.6lf
    " , res);
       return 0;
    }
    
    int youngore = thestars();
    
    signed main() {;}
    
  • 相关阅读:
    C#中的委托,匿名方法和Lambda表达式
    模式化窗口问题![window.dialogArguments]
    js动态改变HiddenField值,后台不能获取值的问题
    将DataTable进行分页并生成新的DataTable
    出错提示为:该行已经属于另一个表 的解决方法
    如何在服务器端获得showModalDialog传递的参数
    Synchronized和SyncRoot与 集合类 的同步
    Oracle中数据出现####的问题
    如何防止多次提交按钮造成重复提交
    Invoke and BeginInvoke
  • 原文地址:https://www.cnblogs.com/yszhyhm/p/13497260.html
Copyright © 2011-2022 走看看