题干:

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,显然删除边 2↔32↔3是最优的。

备注:

2≤S≤N≤105,M=N−12≤S≤N≤105,M=N−1,保证答案在 C++ long long 范围内。

解题报告:

不算难的树形dp,刚开始读题错了,所以代码不太对、、

于是题目转变求为了一棵根为 S 的树,选择性切掉一些边,使得所有的叶子都不能到达根的最小代价。
让我们考虑树形dp(其实可能就是个统计算不上dp):设 fv 表示使得以 v 为根的子树内的叶子到不了 v 的最小代价,转移显然枚举每一条边切不切就可以了。
方程大概是这样:设当前我们要更新的点是 u,u 的一个儿子是 v,他们之间的边的边权是 w。则有转移方程 fu+=min{fv,w}。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<ctime>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
int t;
int n,m,s,tot;
int head[MAX];
int in[MAX];
struct Edge{int u,v,ne;ll w;
} e[MAX];
void add(int u,int v,ll w) {e[++tot].u = u;e[tot].v = v;e[tot].w = w;e[tot].ne = head[u];head[u] = tot;
}
ll dfs(int cur,int root,ll val) {//ll res = 9223372036854775807;ll tmp = 0;for(int i = head[cur]; i!=-1; i=e[i].ne) {if(e[i].v == root) continue;//res = min(res,e[i].w);if(in[e[i].v] == 1) {tmp += e[i].w;continue;}
//      if(in[e[i].v] == 1) continue;tmp += dfs(e[i].v,cur,e[i].w);}return min(tmp,val);
}
int main()
{cin>>n>>m>>s;memset(head,-1,sizeof head);int a,b;ll c;for(int i = 1; i<=m; i++) {scanf("%d%d%lld",&a,&b,&c);add(a,b,c);add(b,a,c);in[a]++,in[b]++;}ll ans = 0;for(int i = head[s]; i != -1; i = e[i].ne) {if(in[e[i].v] == 1) ans += e[i].w;else ans += dfs(e[i].v,s,e[i].w); } printf("%lld\n",ans);return 0 ;
}

错误代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<ctime>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
int t;
int n,m,s,tot;
int head[MAX];
int in[MAX];
struct Edge{int u,v,ne;ll w;
} e[MAX];
void add(int u,int v,ll w) {e[++tot].u = u;e[tot].v = v;e[tot].w = w;e[tot].ne = head[u];head[u] = tot;
}
ll dfs(int cur,int root) {ll res = 9223372036854775807;//int isye = 1;for(int i = head[cur]; i!=-1; i=e[i].ne) {if(e[i].v == root) continue;//isye = 0;res = min(res,e[i].w);if(in[e[i].v] == 1) {continue;}res = min(res,dfs(e[i].v,cur));}//if(isye == 1) returnreturn res;
}
int main()
{cin>>n>>m>>s;memset(head,-1,sizeof head);int a,b;ll c;for(int i = 1; i<=m; i++) {scanf("%d%d%lld",&a,&b,&c);add(a,b,c);add(b,a,c);in[a]++,in[b]++;}ll ans = 0;for(int i = head[s]; i != -1; i = e[i].ne) {if(in[e[i].v] == 1) ans += e[i].w;else ans += dfs(e[i].v,s);}printf("%lld\n",ans);return 0 ;
}

AC代码2:

#include<bits/stdc++.h>
using namespace std;
int n,m,s;
struct edge
{int to;int cost;
};
vector<edge> e[110005];
bool vis[100005];
int mem[100005];
long long dp(int i,int pre)
{if(e[i].size()==1&&i!=s){return e[i][0].cost;}if(mem[i]!=-1)return mem[i];vis[i]=1;long long res=0;int nxt;int co;edge tmp;for(int j=0;j<e[i].size();j++){tmp=e[i][j];nxt=tmp.to;if(vis[nxt])continue;co=tmp.cost;res+=dp(nxt,min(co,pre));}res=min(res,(long long)pre);mem[i]=res;return res;
}
int main()
{//freopen("in.txt","r",stdin);memset(mem,-1,sizeof(mem));scanf("%d%d%d",&n,&m,&s);int u,v,w;edge tmp;for(int i=1;i<=m;i++){scanf("%d%d%d",&u,&v,&w);tmp.cost=w;tmp.to=v;e[u].push_back(tmp);tmp.to=u;e[v].push_back(tmp);}long long ans=dp(s,0x3f3f3f3f);cout<<ans<<endl;return 0;
}

官方标程:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>#define Re register
#define LL long long
#define U unsigned
#define FOR(i,a,b) for(Re int i = a;i <= b;++i)
#define ROF(i,a,b) for(Re int i = a;i >= b;--i)
#define SFOR(i,a,b,c) for(Re int i = a;i <= b;i+=c)
#define SROF(i,a,b,c) for(Re int i = a;i >= b;i-=c)
#define CLR(i,a) memset(i,a,sizeof(i))
#define BR printf("--------------------\n")
#define DEBUG(x) std::cerr << #x << '=' << x << std::endlconst int MAXN = 100000+5;struct Edge{int to,w,next;
}e[MAXN<<1];
int head[MAXN],cnt;
LL f[MAXN];inline void add(int u,int v,int w){e[++cnt] = (Edge){v,w,head[u]};head[u] = cnt;
}void dfs(int v,int fa=0){bool flag = true;for(int i = head[v];i;i = e[i].next){if(e[i].to == fa) continue;flag = false;dfs(e[i].to,v);f[v] += std::min(1ll*e[i].w,f[e[i].to]);}if(flag) f[v] = INT_MAX;
}int N,root;int main(){scanf("%d%*d%d",&N,&root);FOR(i,1,N-1){int u,v,w;scanf("%d%d%d",&u,&v,&w);add(u,v,w);add(v,u,w);}dfs(root);printf("%lld\n",f[root]);return 0;
}

【牛客 - 370F】Rinne Loves Edges(树,统计dp)相关推荐

  1. Rinne Loves Edges

    Rinne Loves Edges 题意: 有n给点,m个边,每个边有边权,给你一个点S,问最少花多少代价,可以让叶子节点无法与S点连通 题解: dp[u]:表示u到叶子节点的最短费用的和 dp[u] ...

  2. 牛客网数据库SQL实战60—— 统计salary的累计和running_total

    牛客网数据库SQL实战60-- 统计salary的累计和running_total 题目描述 按照salary的累计和running_total,其中running_total为前两个员工的salar ...

  3. 牛客 Cutting Bamboos (主席树)

    题解 - 牛客 Cutting Bamboos (主席树) 题目链接: https://ac.nowcoder.com/acm/contest/889/H 题意: 给你一些竹子,q个询问,问你从第l到 ...

  4. 牛客 - 阔力梯的树(树上启发式合并)

    题目链接:点击查看 题目大意:给出一棵树,每个节点都有一个编号,现在规定每个节点的"结实程度"为其子树中所有的编号排序后相邻两个数之差的平方和,现在需要求出每个节点的"结 ...

  5. 【每日一题】4月1日题目 Rinne Loves Edges

    牛客网 链接:https://ac.nowcoder.com/acm/problem/22598 来源:牛客网 题目: 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K, ...

  6. 【牛客 - 157D】插排树(dfs,树形dp)

    题干: 链接:https://ac.nowcoder.com/acm/contest/157/D 来源:牛客网 一年一度的山东省oi夏令营又开始了,每到这个季节,山东的oier们都会欢聚这里,一起学( ...

  7. 牛客练习赛52.Galahad(树状数组维护区间不相同数的和)

    链接:https://ac.nowcoder.com/acm/contest/1084/B 来源:牛客网 Galahad 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K ...

  8. 【Shell牛客刷题系列】SHELL1 统计文件的行数:学习wc命令和文本三剑客awk、grep、sed命令

    该系列是基于牛客Shell题库,针对具体题目进行查漏补缺,学习相应的命令. 刷题链接:牛客题霸-Shell篇. 该系列文章都放到专栏下,专栏链接为:<专栏:Linux>.欢迎关注专栏~ 本 ...

  9. 牛客练习赛52 B.Galahad (树状数组)

    B.Galahad 链接:https://ac.nowcoder.com/acm/contest/1084/B 来源:牛客网 题目描述 魔女要测试骑士的能力,要求他维护一个长度为 的序列,每次要询问一 ...

  10. 牛客练习赛24题解(搜索,DP)

    A题,C题不讲,基础题(但是我要抨击一下这次比赛,卡cin,cout,卡的太狠了,根本就不让过的那种,QAQ) 链接:https://www.nowcoder.com/acm/contest/157/ ...

最新文章

  1. Linux中如何使用Sipcalc计算IP子网
  2. Java数据结构与算法(一) 数组
  3. python fixture_python pytest进阶之xunit fixture详解
  4. 导轨式网管型工业交换机优势具体在哪里呢?
  5. JFinal常量配置学习笔记
  6. kind富文本编辑器_在项目中集成富文本编辑器
  7. [导入]正则表达式学习心得体会(3)(转)
  8. 整理下开发中常用的第三方库
  9. HMS Core 携优势亮相华为发布会,与苹果谷歌三足鼎立
  10. Apache部署多个WordPress网站
  11. 力扣题:904.水果成篮
  12. 拳皇重生服务器维护,《拳皇97 OL》3月8日更新维护公告
  13. HW--DSF服务配置文件
  14. 数据线三合一充电线方案(苹果安卓Type-c充电线) LDR6020
  15. 国内cn域名过期失效日期计算方式
  16. 这篇文章记录平时学习、项目中遇到的问题(未解决的居多)
  17. spotify mp3_为什么Spotify有那么多怪异的通用艺术家,例如白噪声婴儿睡眠
  18. Docker学习(二):安装软件
  19. SqlParameter[]写法
  20. 4084 号码牌(并查集)

热门文章

  1. 641. Design Circular Deque
  2. 719. Find K-th Smallest Pair Distance
  3. [Leedcode][JAVA][第1014题][最佳观光组合][数组][暴力优化]
  4. leetcode 42 接雨水 单调栈
  5. HDU-4793 Collision 计算几何 解方程
  6. 简述汇编语言中的标号有什么规定_2020年秋季学期《汇编语言》在线考试 (适用于2020年12月份考试)【答案标准】...
  7. 计算机四级考试题数据库,计算机四级考试《数据库系统工程师》试题及答案
  8. python collections模块_Python 的collections模块
  9. java创建对象过七夕,想 new 个对象过七夕,她却抛了异常
  10. sprintf函数_三分钟学 Go 语言——函数深度解析(下) 可变参数