【JZOJ4887】【NOIP2016提高A组集训第13场11.11】最大匹配
来源:互联网 发布:php 两个日期相差天数 编辑:程序博客网 时间:2024/04/28 02:54
题目描述
mhy12345学习了二分图匹配,二分图是一种特殊的图,其中的点可以分到两个集合中,使得相同的集合中的点两两没有连边。
图的“匹配”是指这个图的一个边集,里面的边两两不存在公共端点。
匹配的大小是指该匹配有多少条边。
二分图匹配我们可以通过匈牙利算法得以在O(VE)时间复杂度内解决。
mhy12345觉得单纯的二分图匹配算法毫无难度,因此提出新的问题:
现在给你一个N个点N-1条边的连通图,希望你能够求出这个图的最大匹配以及最大匹配的数量。
两个匹配不同当且仅当存在一条边在第一个匹配中存在而在第二个匹配中不存在。
数据范围
分析与演绎
演绎直接得出树形动态规划。
设f[i]表示取i的最大匹配数,F[i]为这个情况下的方案数;
g[i]表示不取i的最大匹配数,G[i]为这个情况下的方案数。
转移方程显然。
代码
#include<iostream>#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#define write(x) (cout<<(x))#define writeln(x) (cout<<(x)<<endl)#define ll long longusing namespace std;const char* fin="hungary.in";const char* fout="hungary.out";const ll inf=0x7fffffff;const ll maxn=100008,maxm=maxn*2,mo=1000000007;ll t,m,n,i,j,k;ll f[maxn],F[maxn],g[maxn],G[maxn],h[maxn],H[maxn];ll fi[maxn],la[maxm],ne[maxm],tot=0;void add_line(ll a,ll b){ tot++; ne[tot]=fi[a]; la[tot]=b; fi[a]=tot;}ll read(){ ll x=0; char ch=getchar(); while (ch<'0' && ch>'9') ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); return x;}ll qpower(ll a,ll b){ ll c=1; while (b){ if (b&1) c=c*a%mo; a=a*a%mo; b>>=1; } return c;}ll N(ll a){ return qpower(a,mo-2);}void dfs(ll v,ll from){ ll i,j=0,k,sum=0,times=1; f[v]=0; F[v]=0; g[v]=0; G[v]=1; for (k=fi[v];k;k=ne[k]) if (la[k]!=from){ dfs(la[k],v); g[v]+=h[la[k]]; G[v]=G[v]*H[la[k]]%mo; sum+=h[la[k]]; times=times*H[la[k]]%mo; j=1; } for (k=fi[v];k;k=ne[k]){ if (la[k]!=from){ if (f[v]<sum-h[la[k]]+g[la[k]]+1){ f[v]=sum-h[la[k]]+g[la[k]]+1; F[v]=times*N(H[la[k]])%mo*G[la[k]]%mo; }else if (f[v]==sum-h[la[k]]+g[la[k]]+1) F[v]=(F[v]+times*N(H[la[k]])%mo*G[la[k]]%mo)%mo; } } if (f[v]>g[v]) h[v]=f[v],H[v]=F[v]; else if (f[v]<g[v]) h[v]=g[v],H[v]=G[v]; else h[v]=f[v],H[v]=(F[v]+G[v])%mo;}int main(){ freopen(fin,"r",stdin); freopen(fout,"w",stdout); t=read(); m=read(); while (t--){ tot=0; memset(fi,0,sizeof(fi)); n=read(); for (i=1;i<n;i++){ j=read(); k=read(); add_line(j,k); add_line(k,j); } dfs(1,0); write(h[1]); if (m==2) write(" "),write(H[1]); write(endl); } return 0;}
启发
写动态规划之前,一定要明确动态规划转移方程。
1 0
- 【JZOJ4887】【NOIP2016提高A组集训第13场11.11】最大匹配
- JZOJ4887. 【NOIP2016提高A组集训第13场11.11】最大匹配
- jzoj 4887. 【NOIP2016提高A组集训第13场11.11】最大匹配 树形dp
- 【NOIP2016提高A组集训第13场11.11】最大匹配
- 【NOIP2016提高A组集训第13场11.11】最大匹配
- 【NOIP2016提高A组集训第13场11.11】最大匹配
- 【NOIP2016提高A组集训第13场11.11】字符串
- NOIP2016提高A组集训第13场11.11 总结
- JZOJ4886【NOIP2016提高A组集训第13场11.11】字符串
- 【JZOJ4886】【NOIP2016提高A组集训第13场11.11】字符串
- 【NOIP2016提高A组集训第3场10.31】方程式
- 【NOIP2016提高A组集训第5场11.2】夕阳
- 方程式 【NOIP2016提高A组集训第3场10.31】
- 【NOIP2016提高A组集训第7场11.4】连锁店
- NOIP2016提高A组集训第8场11.5 总结
- 【NOIP2016提高A组集训第9场11.7】Simple
- NOIP2016提高A组集训第8场11.5总结
- 【NOIP2016提高A组集训第9场11.7】平均数
- 利用Office组件MODI识别图片上的文本 - [技巧攻略]
- 写一个宏,将一个数的奇数位和偶数位交换
- 从赞美和欣赏别人开始
- Spring入门
- TCP协议,UDP协议,TCP/IP的区别
- 【JZOJ4887】【NOIP2016提高A组集训第13场11.11】最大匹配
- 【数据结构与算法】计数排序
- VR系列——Oculus Audio sdk文档:二、Oculus音频SDK指南(1~2)——SDK内容和特点及要求
- GDAL学习笔记——OGR投影(一)
- 使用MODI(Microsoft Office Document Imaging)识别中文,但无法区分段落
- Unity3D开发小贴士(七)Lua里扩展C#对象
- Java应用缓存介绍与LRU(Least Recently Used)算法
- Cookie的弊端
- 读书笔记(4) 数据库