zoukankan      html  css  js  c++  java
  • 3257: 树的难题

    3257: 树的难题

    https://www.lydsy.com/JudgeOnline/problem.php?id=3257

    分析:

      状态只与黑点有0个,大于0个,和白点有0个,1个,大于1个这六个状态有关系。f[u][0/1][0/1/2]表示以u为根的子树最小花费。

      转移方程有点难写!!!

    代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<cctype>
     7 #include<set>
     8 #include<vector>
     9 #include<queue>
    10 #include<map>
    11 using namespace std;
    12 typedef long long LL;
    13 
    14 inline int read() {
    15     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    16     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    17 }
    18 
    19 const int N = 300100;
    20 const LL INF = 1e18;
    21 
    22 int head[N], nxt[N << 1], to[N << 1], len[N << 1], col[N];
    23 LL f[N][2][3], g[2][3];
    24 int En;
    25 
    26 void add_edge(int u,int v,int w) {
    27     ++En; to[En] = v; len[En] = w; nxt[En] = head[u]; head[u] = En;
    28     ++En; to[En] = u; len[En] = w; nxt[En] = head[v]; head[v] = En;
    29 }
    30 
    31 void update(int u,int v,int w) {
    32     for (int a=0; a<=1; ++a) 
    33         for (int b=0; b<=2; ++b) g[a][b] = INF;
    34     for (int a=0; a<=1; ++a) // 原来树上的黑点 
    35         for (int b=0; b<=2; ++b) // 原来书上的白点 
    36             if (f[u][a][b] != INF) 
    37                 for (int c=0; c<=1; ++c) // 子树的黑点 
    38                     for (int d=0; d<=2; ++d) // 子树的白点 
    39                         if (f[v][c][d] != INF) {
    40                             int p1 = a + c >= 1 ? 1 : 0, p2 = b + d >= 2 ? 2 : b + d;  
    41                             g[p1][p2] = min(g[p1][p2], f[u][a][b] + f[v][c][d]); // 原来树上的+子树上的 
    42                             if (!c || d < 2) g[a][b] = min(g[a][b], f[u][a][b] + f[v][c][d] + w); // 断开这条边,使得子树合法 
    43                         }
    44     memcpy(f[u], g, sizeof(g));
    45 }
    46 
    47 void dfs(int u,int fa) {
    48     for (int a=0; a<=1; ++a) 
    49         for (int b=0; b<=2; ++b) f[u][a][b] = INF;
    50     f[u][col[u]==0][col[u]==1] = 0;
    51     for (int i=head[u]; i; i=nxt[i]) {
    52         int v = to[i];
    53         if (v == fa) continue;
    54         dfs(v, u);
    55         update(u, v, len[i]);
    56     }
    57 }
    58 
    59 void solve() {
    60     int n = read();
    61     En = 0;
    62     memset(head, 0, sizeof(head)); //---
    63     for (int i=1; i<=n; ++i) col[i] = read();
    64     for (int i=1; i<n; ++i) {
    65         int u = read(), v = read(), w = read();
    66         add_edge(u, v, w);
    67     }
    68     dfs(1, 0);
    69     LL Ans = min(min(f[1][0][0], f[1][0][1]), f[1][0][2]);
    70     Ans = min(Ans, min(f[1][1][0], f[1][1][1]));
    71     cout << Ans << "
    ";
    72 }
    73 
    74 int main() {
    75     int T = read();
    76     while (T --) solve();
    77     return 0;
    78 }
  • 相关阅读:
    架构之美阅读笔记05
    架构之美阅读笔记04
    已经导入到VS工具箱中的DevExpress如何使用
    C#中遇到的方法总结
    vs下C# WinForm 解决方案里面生成的文件都是什么作用?干什么的?
    ssh关于含有外键的传值中无法识别正确的action的原因和解决办法
    MVC模式在Java Web应用程序中的实例分析
    浅谈对MVC的理解
    简述23种设计模式
    浅谈对可用性和易用性的认识以及对如何增加系统功能的理解
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9645010.html
Copyright © 2011-2022 走看看