w
时间:2019-10-02
本文章向大家介绍w,主要包括w使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
dp
题解
首先第一问就是奇度点个数/2
直接$dp$不好$dp$,考虑关于奇度点来设立
边权下放到节点
$f[x][0/1]$结构体定义,$f[x][0].c1$表示$x$与父亲连边不反转时奇度点个数,$f[x][0].c2$表示$x$与父亲连边翻转是要的最小操作数$f[x][1]$表示翻转
转移就是分情况讨论,我们首先要将子树合并完,最后再上传到当前节点
w1表示子树有一条边指向当前节点代价(奇度点个数为奇)
w2表示子树没有边指向当前节点代价(奇度点个数为偶)
分别转移
$w1=min(w2+f[y][1],w1+f[y][0])$
解释一下保证奇度点个数为奇可以是当前已考虑子树内两两合,并翻转当前这条边;或者已考虑子树内伸出一条边当前边不伸
$w2=min(w1+f[y][1],w2+f[y][0])$
和上面类似
那么对于当前来说
$f[x][0]$由两部分转移,可以是没操作$w2$可以当前点和子树一奇度点结合$c1=w1.c1+1,c2=w1.c2$(路径长度不+1是因为在下面统计过了)
$f[x][1]$由两部分转移,可以是让子树伸的边继续延伸$c1=w1.c1,c2=w1.c2+1$可以是当前边翻转然后当前点成为奇点$c1=w2.c1+1,c2=w2.c2+1$
代码
#include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1e9+7 #define A 1111111 ll head[A],nxt[A],ver[A],edg[A]; ll tot,n; void add(ll x,ll y,ll opt){ nxt[++tot]=head[x],head[x]=tot,ver[tot]=y,edg[tot]=opt; } struct node{ ll c1,c2; node(){} node (const ll &a,const ll &b){ c1=a,c2=b; } friend bool operator < (const node &a,const node &b){ return (a.c1==b.c1)?(a.c2<b.c2):(a.c1<b.c1); } friend node operator +(const node &a,const node &b){ node c;c.c1=0,c.c2=0; c.c1=a.c1+b.c1,c.c2=a.c2+b.c2; return c; } }f[A][2]; void dfs(ll x,ll pre,ll opt){ node w1(inf,inf),w2(0,0),n1,n2; for(ll i=head[x];i;i=nxt[i]){ ll y=ver[i]; if(y==pre) continue ; dfs(y,x,edg[i]); n1=min(w1+f[y][0],w2+f[y][1]); n2=min(w2+f[y][0],w1+f[y][1]); w1=n1,w2=n2; } // printf("w1.c1=%lld w1.c2=%lld w2.c1=%lld w2.c2=%lld\n",w1.c1,w1.c2,w2.c1,w2.c2); if(opt==2){ f[x][1]=min(node(w1.c1,w1.c2+1),node(w2.c1+1,w2.c2+1)); f[x][0]=min(node(w1.c1+1,w1.c2),node(w2.c1,w2.c2)); } else if(opt==1){//must f[x][1]=min(node(w1.c1,w1.c2+1),node(w2.c1+1,w2.c2+1)); f[x][0]=node(inf,inf); } else if(opt==0){//must`not f[x][0]=min(node(w1.c1+1,w1.c2),node(w2.c1,w2.c2)); f[x][1]=node(inf,inf); } } int main(){ scanf("%lld",&n); for(ll i=1;i<n;i++){ ll x,y,opt,case1,case2; scanf("%lld%lld%lld%lld",&x,&y,&case1,&case2); if(case2==2){ add(x,y,2);add(y,x,2); } else if(case1==case2){ add(x,y,0);add(y,x,0); } else if(case1!=case2){ add(x,y,1);add(y,x,1); } } dfs(1,0,0); printf("%lld %lld\n",f[1][0].c1>>1,f[1][0].c2); }
原文地址:https://www.cnblogs.com/znsbc-13/p/11616702.html
- 微信快速开发框架(八)-- V2.3--增加语音识别及网页获取用户信息,代码已更新至Github
- 微信公众平台快速开发框架 For Core 2.0 beta –JCSoft.WX.Core 5.2.0 beta发布
- Android系统层Watchdog机制源码分析
- 算法之插入排序
- Android Studio环境下搭建ReactNative
- Android实现两个ScrollView互相联动,同步滚动的效果
- 一个可以拖动的自定义Gridview代码
- android图片加载库Glide
- 密码最短长度为7,其中必须包含以下非字母数字字符1 完美解决方案
- android开发性能分析
- url带中文参数显示乱码的问题
- 转换程序的一些问题:设置为 OFF 时,不能为表 'Test' 中的标识列插入显式值。8cad0260
- JQuery 对控件的事件操作
- 流畅地HtmlHelper-Asp.Net MVC
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python测试开发django-83.Dockerfile部署django项目
- python测试开发django-82.线上部署设置DEBUG=FALSE
- BCEL ClassLoader去哪了
- python接口自动化35-r.html.render() 下载无反应问题解决
- 源码编译搭建Spark3.x环境
- 搭建Hive3.x并整合MySQL8.x存储元数据
- MySQL binlog_error_action分析
- docker(数据卷容器)
- Python炫技操作:模块重载的五种方法
- 一文搞定 Eureka 集群高可用配置
- SpringBoot三招组合拳,手把手教你打出优雅的后端接口
- 在bootstrap中col-md-offset-* 偏移不起作用
- ES6 模糊查询 智能联想(不区分大小写)
- 干货分享 | K8s 、Docker 常用命令汇总
- 干货 | YOLOV5 训练自动驾驶数据集,并转Tensorrt,收藏!