牛客暑期第六场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 ...
随机推荐
- 【NOI2019模拟2019.7.1】三格骨牌(轮廓线dp转杨图上钩子定理)
Description \(n,m<=1e4,mod ~1e9+7\) 题解: 显然右边那个图形只有旋转90°和270°后才能放置. 先考虑一个暴力的轮廓线dp: 假设已经放了编号前i的骨牌,那 ...
- 「题解」:y
问题 B: y 时间限制: 1 Sec 内存限制: 256 MB 题面 题面谢绝公开. 题解 考虑双向搜索. 定义$cal_{i,j,k}$表示当前已经搜索状态中是否存在长度为i,终点为j,搜索过边 ...
- 依赖背包优化——ural1018,金明的预算方案
经典题了,网上博客一大堆O(nCC)的做法,其实是可以将复杂度降到O(nC)的 参考依赖背包优化(泛化物品的并) 根据背包九讲,求两个泛化物品的和复杂度是O(CC)的,所以依赖背包暴力求解的复杂度是O ...
- NX二次开发-UFUN将目录与文件名组合在一起uc4575
NX11+VS2013 #include <uf.h> #include <uf_ui.h> #include <uf_cfi.h> UF_initialize() ...
- NX二次开发-NXOPEN自动切换到工程图模块
UFUN的API里是没有切换到工程图的函数的,NXOPEN里是有方法可以用的.不过应该是不支持NX9以下的版本. NX9的不能录制出来,在UI类里有方法 NX9+VS2012 #include < ...
- (转)在Struts 2.0中国际化(i18n)您的应用程序 + 本人拓展备注
转:http://www.blogjava.net/max/archive/2006/11/01/78536.html 国际化是商业系统中不可或缺的一部分,所以无论您学习的是什么Web框架,它都是必须 ...
- (转) mysql的分区技术 .
转:http://blog.csdn.net/feihong247/article/details/8100960 一.概述 当 MySQL的总记录数超过了100万后,会出现性能的大幅度下降吗?答案是 ...
- 54Mbps、150Mbps、433Mbps 你知道这三个Wi-Fi速率怎么算的吗?
802.11g能够提供54Mbps的最大速率, 802.11n和802.11ac单流分别能够提供150Mbps和433Mbps的最大速率,这些数字是怎么算的呢?(看红字,更容易理解哟) ...
- 引入css文件时,css link和@import区别
这里link与@import介绍的是html引入css的语法单词.两者均是引入css到html的单词. 一.了解基本 1.link语法结构 <link href="CSSurl路径&q ...
- Hbase启动的时候出现:[RpcServer.handler=28,port=60000] ipc.RpcServer: RpcServer.handler=28,port=60000: exiting,master.HMasterCommandLine: Master exiting
hadoop 版本:CDH5.02 Hbase 版本:hbase-0.96.1.1-cdh5.0.2 配置文件:hbase-site.xml <configuration> <pro ...