CF891D Sloth
题意:给你一棵树,你选择删掉一条边,再加上一条边(也要保证为树),问最后树上的节点能够两两完美匹配的加删边方案数?
n<=5e5.
标程:
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int read()
{
int x=;char ch=getchar();
while (ch<''||ch>'') ch=getchar();
while (''<=ch&&ch<='') x=(x<<)+(x<<)+ch-'',ch=getchar();
return x;
}
const int N=;
typedef long long ll;
int size[N],n,u,v;
ll ans;
vector<int> vec[N];
struct node{int a[][];}f[N],g[N];
vector<node> pre[N];
void init(node &x){x.a[][]=;x.a[][]=x.a[][]=x.a[][]=;}
node modi(node x,node y)
{
node c;
c.a[][]=x.a[][]*y.a[][];
c.a[][]=x.a[][]*y.a[][]+x.a[][]*y.a[][];
c.a[][]=x.a[][]*y.a[][]+x.a[][]*(y.a[][]+y.a[][]);
c.a[][]=x.a[][]*y.a[][]+x.a[][]*(y.a[][]+y.a[][])+x.a[][]*y.a[][]+x.a[][]*y.a[][];
return c;
}
node merge(node x,node y)
{
node c;
c.a[][]=x.a[][]*y.a[][];
c.a[][]=x.a[][]*y.a[][]+x.a[][]*y.a[][];
c.a[][]=x.a[][]*y.a[][]+x.a[][]*y.a[][];
c.a[][]=x.a[][]*y.a[][]+x.a[][]*y.a[][]+x.a[][]*y.a[][]+x.a[][]*y.a[][];
return c;
}
void dp1(int x,int fa)
{
size[x]=;init(f[x]);
if (fa!=-) vec[x].erase(find(vec[x].begin(),vec[x].end(),fa));//将fa删去,方便前后缀的处理
for (int i=;i<vec[x].size();i++)
{
int v=vec[x][i]; //注意内部定义
dp1(v,x);size[x]+=size[v];
f[x]=modi(f[x],f[v]);
}
}
void dp2(int x,int fa)
{
node cur;init(cur);
if (fa>) pre[x].push_back(modi(cur,g[x]));else pre[x].push_back(cur);
for (int i=;i<vec[x].size();i++)
pre[x].push_back(modi(pre[x].back(),f[vec[x][i]]));
for (int i=vec[x].size()-;i>=;i--)
{
int v=vec[x][i];
g[v]=merge(pre[x][i],cur);cur=modi(cur,f[v]);
dp2(v,x);
}
}
int main()
{
n=read();if (n&) return puts(""),;
for (int i=;i<n;i++) u=read(),v=read(),vec[u].push_back(v),vec[v].push_back(u);
dp1(,-);dp2(,-);
for (int i=;i<=n;i++)
if (f[i].a[][]&&g[i].a[][]) ans+=(ll)size[i]*(n-size[i]);
else ans+=(ll)(f[i].a[][]+f[i].a[][])*(g[i].a[][]+g[i].a[][]);
printf("%lld\n",ans);
return ;
}
易错点:1.转移式子要认真推。
2.注意函数内部定义变量。
3.将fa在vector中删去,方便前后缀寻址的对应。
题解:dp
把一条边删掉,树就分成了两个子树。要么各自匹配(这样怎么连都可以),要么连一条边后边的端点匹配,也就是两个子树在没有连边前各有一个点没有匹配。
f[i][0/1][0/1]表示以i为根的子树,根是否被匹配,子树中是否恰有一个点未被匹配的未匹配点的选法数。
g表示i为根的子树外的部分的答案(以fa[i]为根)。正反dp两遍后统计答案即可。
CF891D Sloth的更多相关文章
- sloth——算法工程师标注数据的福音
一般算法工程师做标注,都要先开发个标注工具,无非下面几个选项: 1.mfc,C#,优点是交互界面友好,开发难度适中,缺点是没法跨平台 2.matlab,优点是可以跨平台,开发难度非常低,缺点是速度慢. ...
- Seven Deadly Sins: Gluttony, Greed, Sloth, Wrath, Pride, Lust, and Envy.
Seven Deadly Sins: Gluttony, Greed, Sloth, Wrath, Pride, Lust, and Envy.七宗罪:暴食.贪婪.懒惰.暴怒.傲慢.色欲.妒忌.
- Codeforces 891D - Sloth(换根 dp)
Codeforces 题面传送门 & 洛谷题面传送门 换根 dp 好题. 为啥没人做/yiw 首先 \(n\) 为奇数时答案显然为 \(0\),证明显然.接下来我们着重探讨 \(n\) 是偶数 ...
- Java Script 编码规范【转】
Java Script 编码规范 以下文档大多来自: Google JavaScript 编码规范指南 Idiomatic 风格 参考规范 ECMAScript 5.1 注解版 EcmaScript ...
- pickle序列化
通过pickle来序列化: # -*- coding: utf-8 -*- import pickle #-------------------序列化--------------------- zoo ...
- nullcon HackIM 2016 -- Programming Question 5
Dont blink your Eyes, you might miss it. But the fatigue and exhaustion rules out any logic, any wil ...
- C++ Primer Plus读书笔记
第五章 循环和关系表达式 1. 2.类别别名: (1) #define FLOAT_POINTER float * FLOAT_POINTER pa, pb; 预处理器置换将该声明转换成 flo ...
- Deep Learning in a Nutshell: History and Training
Deep Learning in a Nutshell: History and Training This series of blog posts aims to provide an intui ...
- javascript 函数式编程
编程范式 编程范式是一个由思考问题以及实现问题愿景的工具组成的框架.很多现代语言都是聚范式(或者说多重范式): 他们支持很多不同的编程范式,比如面向对象,元程序设计,泛函,面向过程,等等. 函数式编程 ...
随机推荐
- 5.RabbitMQ 客户端控制消息
1.生产者发送消息,消费者结束消息并回执 2.通过channel.basicConsume向服务器发送回执,删除服务上的消息 3.//不向服务器发送回执,服务器的消息一直存在 4.//消费者拒绝接受消 ...
- 洛谷P3916 图的遍历
题目链接:https://www.luogu.org/problemnew/show/P3916 题目大意 略. 分析 以终为始,逆向思维. 代码如下 #include <bits/stdc++ ...
- 如何把本地文件上传github
1.$ git config --global user.name "xxx" 2.$ git config --global user.email xxx@qq.com 3.进入 ...
- Java:关于main方法的10道面试题
感觉假期过得好快,东西也丢得快. 假期吃喝玩乐之余也来温故一下Java知识,下面给大家整理了10道Java main方法的经典面试题,都来挑战一下自己的Java基础知识吧! 1.main方法是做什么用 ...
- .net 超链接传值,传过去始终是null
今天做了一个删除功能,通过点击列表中的删除超链接,通过get请求,跳转到一个处理程序执行删除操作 . 因为不熟悉各种报错 , <%="<td> <a class='d ...
- VB.NET利用正則表達式巧妙限制字符输入
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u010028869/article/details/37913867 在通常的程序设计中.对 ...
- 十个非常实用的MySQL命令
建赟 版主 楼主 前言 今天介绍一些MySQL常用的实用命令,都是一些比较简单的命令.已经知道的朋友,就当是巩固吧,不知道的童鞋,可以好好在自己的机器上,练习下. 0. 显示数据库 命令:s ...
- 简单的GridView分业,后台不需要写
1前台代码: <asp:GridView ID="GridView1" runat="server" AllowPaging="True&quo ...
- python、Jupyter运行时间
1.Python time time()方法 import time time_start=time.time() time_end=time.time() print('totally cost', ...
- 【CSP-S/J 2019】初赛注意事项
UPD:10-25-13:33 正式成绩出了,省里500多名应该进了吧... UPD:10-20-10:07 现在又很慌啊,怎么感觉82又一点都不稳啊... 然后现在又不太想写文化课作业...我是不是 ...