牛客暑期第六场G /// 树形DP 最大流最小割定理
题目大意:
输入t,t个测试用例
每个测试用例输入n
接下来n行 输入u,v,w,树的无向边u点到v点权重为w
求任意两点间的最大流的总和
1.最大流最小割定理 即最大流等于最小割
2.无向树上的任意两点都可互达 也就是说 源点S可经其他任何点流到汇点T
设dist(x , y) 为在树上 x 到 y 的距离
由2能知道,S的总流量就是 n∑i=1 dis( s , i )
然后就是题解上的 S到其他各个点的距离 和 T到其他各个点的距离 中较小的即为最小割

举个栗子
4
1 2 3
1 3 4
3 4 5

通过树形DP
ll dis[MAXN], son[MAXN], dp[MAXN]; /// dis[ i ]为从 i 点向下的分支的长度总和
/// son[ i ]为从 i 点向下的总点数(包括它本身)
/// dp[ i ]为从 i 点出发去其他所有点的长度总和 void dfs1(ll u,ll f) /// 求dis[],son[]
{
son[u]=;
for(int i=;i<vec[u].size();i++) {
ll v=vec[u][i].F, w=vec[u][i].S;
if(v==f) continue;
dfs1(v,u);
son[u]+=son[v];
dis[u]+=dis[v]+son[v]*w;
}
} void dfs2(int u,int f) /// 通过dis[]进行树形DP
{
for(int i=;i<vec[u].size();i++) {
ll v=vec[u][i].F, w=vec[u][i].S;
if(v==f) continue;
dp[v]=dp[u]+(n-*son[v])*w;
dfs2(v,u);
}
}
...... dfs1(,); dp[]=dis[]; dfs2(,); ......
/*结果为
dis[] 16 0 5 0
son[] 4 1 2 1 dp[] 16 22 16 26
*/
可以转化为一个(姑且称之为)流量图

括号内的是到该点的总流量
那么 S到T的最大流 就是 两者总流量中 小的一个
sort(dp+,dp++n);
__int128 ans=;
for(int i=;i<n;i++)
ans += dp[i]*(n-i);
当某个点x的总流量是所有点中的最小值时
那么x与其他所有点的最大流就是x的总流量
所以这里可以直接贪心 排序一下
第 i 个点与后面比它(的总流量)小的所有点(n - i 个)直接取第 i 个
也可以不用 __int128 ,开个数组模拟一下
int ans[];
memset(ans,,sizeof(ans));
for(ll i=;i<n;i++) {
ans[] += dp[i]*(n-i);
int j=;
while(ans[j]>=) {
ans[j+] += ans[j]/;
ans[j++] %= ;
}
len=max(len,j);
}
printf("Case #%d: %lld",o,ans[len]);
for(int i=len-;i>=;i--) {
if(ans[i]>=) printf("%lld",ans[i]);
else if(ans[i]>=) printf("0%lld",ans[i]);
else printf("00%lld",ans[i]);
} printf("\n");
完整代码
#include <bits/stdc++.h>
#define P pair<ll,ll>
#define mp(i,j) make_pair(i,j)
#define F first
#define S second
#define MAXN 100005
#define ll long long
using namespace std; vector <P> vec[MAXN];
ll dis[MAXN], son[MAXN], dp[MAXN];
ll n, m, ans[MAXN]; void dfs1(ll u,ll f)
{
son[u]=;
for(int i=;i<vec[u].size();i++) {
ll v=vec[u][i].F, w=vec[u][i].S;
if(v==f) continue; dfs1(v,u); son[u]+=son[v];
dis[u]+=dis[v]+son[v]*w;
}
} void dfs2(int u,int f)
{
for(int i=;i<vec[u].size();i++) {
ll v=vec[u][i].F, w=vec[u][i].S;
if(v==f) continue; dp[v]=dp[u]+(n-*son[v])*w; dfs2(v,u);
}
} int main()
{
int t; scanf("%d",&t);
for(int o=;o<=t;o++) {
for(int i=;i<=n;i++) vec[i].clear();
memset(dis,,sizeof(dis));
memset(son,,sizeof(son));
memset(dp,,sizeof(dp)); scanf("%lld",&n);
for(int i=;i<n;i++) {
ll u,v,w; scanf("%lld%lld%lld",&u,&v,&w);
vec[u].push_back(mp(v,w));
vec[v].push_back(mp(u,w));
} dfs1(,); dp[]=dis[]; dfs2(,);
sort(dp+,dp++n); int len=;
memset(ans,,sizeof(ans));
for(ll i=;i<n;i++) {
ans[] += dp[i]*(n-i);
int j=;
while(ans[j]>=) {
ans[j+] += ans[j]/;
ans[j++] %= ;
}
len=max(len,j);
} printf("Case #%d: %lld",o,ans[len]);
for(int i=len-;i>=;i--) {
if(ans[i]>=) printf("%lld",ans[i]);
else if(ans[i]>=) printf("0%lld",ans[i]);
else printf("00%lld",ans[i]);
} printf("\n");
} return ;
}
数组模拟
#include <bits/stdc++.h>
#define P pair<int,int>
#define mp(i,j) make_pair(i,j)
#define F first
#define S second
#define MAXN 100005
using namespace std;
vector <P> vec[MAXN];
int son[MAXN];
int n, m;
__int128 dis[MAXN], dp[MAXN]; void dfs1(int u,int f)
{
son[u]=;
for(int i=;i<vec[u].size();i++) {
int v=vec[u][i].F, w=vec[u][i].S;
if(v==f) continue; dfs1(v,u); son[u]+=son[v];
dis[u]+=dis[v]+son[v]*w;
}
} void dfs2(int u,int f)
{
for(int i=;i<vec[u].size();i++) {
int v=vec[u][i].F, w=vec[u][i].S; if(v==f) continue; dp[v]=dp[u]+(n-*son[v])*w; dfs2(v,u);
}
} void print(__int128 ans)
{
if(ans>) print(ans/);
printf("%c",''+ans%);
} int main()
{
int t; scanf("%d",&t);
for(int o=;o<=t;o++) { for(int i=;i<=n;i++) vec[i].clear();
memset(dis,,sizeof(dis));
memset(son,,sizeof(son));
memset(dp,,sizeof(dp)); scanf("%d",&n);
for(int i=;i<n;i++) {
int u,v,w; scanf("%d%d%d",&u,&v,&w);
vec[u].push_back(mp(v,w));
vec[v].push_back(mp(u,w));
} dfs1(,); dp[]=dis[]; dfs2(,); sort(dp+,dp++n);
__int128 ans=;
for(int i=;i<n;i++)
ans += dp[i]*(n-i); printf("Case #%d: ",o);
print(ans);printf("\n");
} return ;
}
__int128
牛客暑期第六场G /// 树形DP 最大流最小割定理的更多相关文章
- run (牛客多校第二场)计数DP
链接:https://www.nowcoder.com/acm/contest/140/A来源:牛客网 题目描述 White Cloud is exercising in the playground ...
- 牛客练习赛32B Xor Path (树形dp)
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 给定一棵n个点的树,每个点有权值.定义表示 ...
- [2019牛客多校第二场][G. Polygons]
题目链接:https://ac.nowcoder.com/acm/contest/882/G 题目大意:有\(n\)条直线将平面分成若干个区域,要求处理\(m\)次询问:求第\(q\)大的区域面积.保 ...
- 牛客多校第二场 G transform
链接:https://www.nowcoder.com/acm/contest/140/G White Cloud placed n containers in sequence on a axes. ...
- 二分图最佳匹配KM算法 /// 牛客暑期第五场E
题目大意: 给定n,有n间宿舍 每间4人 接下来n行 是第一年学校规定的宿舍安排 接下来n行 是第二年学生的宿舍安排意愿 求满足学生意愿的最少交换次数 input 2 1 2 3 4 5 6 7 8 ...
- 2019牛客竞赛第六场D Move 宏观单调,部分不单调
Move 题意 有k个体积相同的箱子,有个憨憨有固定的装箱策略,每次都只装可以装的重量中最大的东西,求箱子的最小提及 分析 看起来可以二分,但由于他的装箱策略有点蠢,所以只在宏观上满足单调性,在特别小 ...
- 牛客小白月赛3---G 旅游(树形dp)
题目链接:https://www.nowcoder.com/acm/contest/87/G 分析: 1.对于点cur,dp[cur][0]表示在该点住宿:dp[cur][1]表示其某个子结点住宿,自 ...
- 2019牛客多校第一场 E-ABBA(dp)
ABBA 题目传送门 解题思路 用dp[i][j]来表示前i+j个字符中,有i个A和j个B的合法情况个数.我们可以让前n个A作为AB的A,因为如果我们用后面的A作为AB的A,我们一定也可以让前面的A对 ...
- 【牛客】路径计数机 (树形dp 前缀和)
题目描述 有一棵n个点的树和两个整数p, q,求满足以下条件的四元组(a, b, c, d)的个数: 1.$1\leq a,b,c,d \leq n$ 2.点a到点b的经过的边数为p. 3.点c ...
随机推荐
- Spring,SpringMVC,SpringBoot,SpringCloud有什么区别和联系?
简单介绍 Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架.Spring使你能够编写更干净.更可管理.并且更易于测试的代码. Spring MVC是Spring的一个模块,一 ...
- 前置控制器一DispatcherServlet
org.springframework.web.servlet.DispatcherServlet 前言 DispatcherServlet是SpringMVC的核心控制器,就像是SpringMVC的 ...
- CF838C(博弈+FWT子集卷积+多项式ln、exp)
传送门: http://codeforces.com/problemset/problem/838/C 题解: 如果一个字符串的排列数是偶数,则先手必胜,因为如果下一层有后手必赢态,直接转移过去,不然 ...
- HBase的应用场景及特点
一.Hbase能做什么?1. 海量数据存储:上百亿行 x 上百万列并没有列的限制当表非常大的时候才能发挥这个作用, 最多百万行的话,没有必要放入hbase中2. 准实时查询:百亿行 x 百万列,在百毫 ...
- Delphi中任务栏状态区的编程
在Windows桌面的任务栏上有一个凹陷的区域,其中显示着系统时钟以及一些图标,这个长方形的区域便是Windows的任务栏状态区(taskbar status area).本文将介绍使用Borland ...
- NX二次开发-bat脚本文件切换NX的环境变量(NX路径和语言)
路径环境变量切换到NX9.bat @echo off setx /M UGII_BASE_DIR "D:\Program Files\Siemens\NX 9.0" ------- ...
- [JZOJ 5807] 简单的区间
题目: 求有多少组二元组\((l,r)\)使得:\(1<=l<=r<=n,k|f(l,r)\) \(f(l,r) = \sum_{i=l}^{r}a_i - max_{i=l}^{r ...
- java基础编程题(2)
1.给定一个二叉树,找出其最大深度. 注:二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. /** * Definition for a binary tree node. * public ...
- 使用SDK方式进行微信授权
1.在pom.xml中添加依赖 <dependency> <groupId>com.github.binarywang</groupId> <artifact ...
- 【收集+】DDR5 vs DDR4
Advantages of Migrating to DDR5 DDR5 is the next evolution in DRAM, bringing a robust list of new fe ...