zoukankan      html  css  js  c++  java
  • 牛客小白月赛11 Rinne Loves Edges(dfs)

     Rinne Loves Edges

    题目描述 

    Rinne  最近了解了如何快速维护可支持插入边删除边的图,并且高效的回答一下奇妙的询问。
    她现在拿到了一个 n 个节点 m 条边的无向连通图,每条边有一个边权 wiwi
    现在她想玩一个游戏:选取一个 “重要点” S,然后选择性删除一些边,使得原图中所有除 S 之外度为 1 的点都不能到达 S。
    定义删除一条边的代价为这条边的边权,现在 Rinne 想知道完成这个游戏的最小的代价,这样她就能轻松到达 rk1 了!作为回报,她会让你的排名上升一定的数量。
     

    输入描述:

    第一行三个整数 N,M,S,意义如「题目描述」所述。

    接下来 M 行,每行三个整数 u,v,w 代表点 u 到点 v 之间有一条长度为 w 的无向边。

    输出描述:

    一个整数表示答案。
    示例1

    输入

    4 3 1 
    1 2 1 
    1 3 1 
    1 4 1
    

    输出

    3

    说明

    需要使得点 2,3,4 不能到达点 1,显然只能删除所有的边,答案为 3
    示例2

    输入

    4 3 1 
    1 2 3 
    2 3 1 
    3 4 2
    

    输出

    1

    说明

    需要使得点 4 不能到达点 1,显然删除边 232↔3是最优的。

    备注:

    2SN105,M=N1,保证答案在 C++ long long 范围内。
    题解:
    通过数据范围 n = m-1 不难发现这是一棵树,注意到树上只有根和叶子的度可能为 1。
    于是题目转变求为了一棵根为 S 的树,选择性切掉一些边,使得所有的叶子都不能到达根的最小代价。
    让我们考虑树形dp(其实可能就是个统计算不上dp):设 fv 表示使得以 v 为根的子树内的叶子到不了 v 的最小代价,转移显然枚举每一条边切不切就可以了。
    方程大概是这样:设当前我们要更新的点是 u,u 的一个儿子是 v,他们之间的边的边权是 w。则有转移方程 fu+=min{fv,w}
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 #include <algorithm>
     6 using namespace std;
     7 typedef long long ll;
     8 const int maxn = 1e5+10;
     9 ll in[maxn];
    10 ll n,m,s,u,v,w;
    11 struct node{
    12     ll to;
    13     ll val;
    14 }head,tail; 
    15 vector<node>g[maxn];
    16 ll dfs(ll pos,ll res,ll root){
    17     ll ans=0;
    18     for(int i=0;i<g[pos].size();i++){
    19         head=g[pos][i];
    20         int to=head.to;
    21         if(to==root)
    22             continue;
    23         else if(in[to]==1){
    24             ans+=head.val;
    25         }
    26         else{
    27             ans+=dfs(to,head.val,pos);
    28         }
    29     }
    30     return min(ans,res);
    31 }
    32 int main()
    33 {
    34     cin>>n>>m>>s;
    35     for(int i=0;i<m;i++){
    36         scanf("%lld %lld %lld",&u,&v,&w);
    37         head.to=v;
    38         head.val=w;
    39         g[u].push_back(head);
    40         head.to=u;
    41         g[v].push_back(head); 
    42         in[u]++;
    43         in[v]++;
    44     }
    45     ll ans=0;
    46     for(int i=0;i<g[s].size();i++){
    47         node tmp=g[s][i];
    48         if(in[tmp.to]==1){
    49             ans+=tmp.val; 
    50         }
    51         else{
    52             ans+=dfs(tmp.to,tmp.val,s);
    53         }
    54     }
    55     printf("%lld
    ",ans);
    56     return 0;
    57 }
     
  • 相关阅读:
    20191324读书笔记10
    20191324读书笔记十一
    实验三:个人贡献
    20191324读书笔记12
    CBMVC For Titanium Alloy 发布!
    让 PowerDesigner 支持 SQLite!
    在类库中调用资源文件实现国际化!
    理解依赖注入及其好处!
    CBMVC Titanium Framework 介绍
    .Net插件框架的实现及分析(二)
  • 原文地址:https://www.cnblogs.com/1013star/p/10363601.html
Copyright © 2011-2022 走看看