NOIP模拟赛 最大匹配
问题描述
mhy12345学习了二分图匹配,二分图是一种特殊的图,其中的点可以分到两个集合中,使得相同的集合中的点两两没有连边。
图的“匹配”是指这个图的一个边集,里面的边两两不存在公共端点。
匹配的大小是指该匹配有多少条边。
二分图匹配我们可以通过匈牙利算法得以在O(VE)时间复杂度内解决。
mhy12345觉得单纯的二分图匹配算法毫无难度,因此提出新的问题:
现在给你一个N个点N-1条边的连通图,希望你能够求出这个图的最大匹配以及最大匹配的数量。
两个匹配不同当且仅当存在一条边在第一个匹配中存在而在第二个匹配中不存在。
输入格式
第一行两个数T,P,其中T表示数据组数。
接下来每组数据第一行一个数N
接下来N-1行每行两个数分别表示一条边。
输出格式
对于每组数据,输出一行:
若p=1,则一行一个数输出图的最大匹配
若p=2,则一行两个数输出图的最大匹配以及最大匹配数量。
输入输出样例一
|
hungary.in |
hungary.out |
|
1 1 2 1 2 |
1 |
题解:
问题可以看成层与层间、父亲和儿子间选和不选的两种情况
选一个节点可以看作选下图中的块:

约定如下:
f[i],选中编号为i的节点的最大匹配;
F[i],选中编号为i的节点的最大匹配的方案数;
g[i],不选编号为i的节点的最大匹配;
G[i],不选编号为i的节点的最大匹配的方案数;
h[i],编号为i节点的最大匹配;
H[i],编号为i节点的最大匹配的方案数;
于是初始的动规方程如下:
g[i]=g[i]+h[son]
G[i]=G[i]*H[son]
f[i]=max(f[i],(∑h[son,son])-h[son]+g[son])
F[i]=(∏H[son])/h[son]*G[son]
#include<stdio.h>
#include<string.h>
#define buf 100001
#define mo 1000000007
typedef long long ll;
inline void S(int &x){
x=;int c=getchar(),f=;
for(;c<||c>;c=getchar())
if(!(c^))
f=-;
for(;c>&&c<;c=getchar())
x=(x<<)+(x<<)+c-;
x*=f;
}
int n,fst[buf],nxt[buf<<],v[buf<<],tot;
ll g[buf],G[buf],f[buf],F[buf],h[buf],H[buf];
inline void link(int a,int b){
v[++tot]=b,
nxt[tot]=fst[a],
fst[a]=tot,
v[++tot]=a,
nxt[tot]=fst[b],
fst[b]=tot;
}
ll P(ll a,ll b){
ll c=;
for(;b;b>>=){
if(b&)
c=c*a%mo;
a=a*a%mo;
}
return c;
}
ll N(ll a){
return P(a,mo-);
}
void D(int x,int fa){
G[x]=;
g[x]=f[x]=F[x]=h[x]=H[x]=;
ll mul=,sum=;
for(int j=fst[x];j;j=nxt[j])
if(v[j]^fa)
D(v[j],x),
g[x]+=h[v[j]],
G[x]=G[x]*H[v[j]]%mo,
sum+=h[v[j]],
mul=mul*H[v[j]]%mo;
for(int j=fst[x];j;j=nxt[j])
if(v[j]^fa)
if(f[x]<sum-h[v[j]]+g[v[j]]+)
f[x]=sum-h[v[j]]+g[v[j]]+,
F[x]=mul*N(H[v[j]])%mo*G[v[j]]%mo;
else
if(!(f[x]^(sum-h[v[j]]+g[v[j]]+)))
F[x]=(F[x]+mul*N(H[v[j]])%mo*G[v[j]]%mo)%mo;
if(f[x]>g[x])
h[x]=f[x],
H[x]=F[x];
else
if(f[x]<g[x])
h[x]=g[x],
H[x]=G[x];
else
h[x]=f[x],
H[x]=(F[x]+G[x])%mo;
}
int main(){
int T,p;
freopen("hungary.in","r",stdin),
freopen("hungary.out","w",stdout);
S(T),S(p);
while(T--){
tot=;
memset(fst,,sizeof(fst));
S(n);
for(int i=,x,y;i<n;i++)
S(x),
S(y),
link(x,y);
D(,);
if(p&)
printf("%I64d\n",h[]);
else
printf("%I64d %I64d\n",h[],H[]);
}
fclose(stdin),
fclose(stdout);
}
NOIP模拟赛 最大匹配的更多相关文章
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...
- 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...
- 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- CH Round #52 - Thinking Bear #1 (NOIP模拟赛)
A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...
随机推荐
- 实验9:Problem G: 克隆人来了!
想要输出""的话: cout<<"A person whose name is \""<<name<<" ...
- Visual Studio将Delop之后生成的dll或者wsp复制到指定目录
用VS开发sharepoint项目的时候,有很多个project,每个project都会生成一个wsp包,如果手工把wsp文件找到,复制出来,拷贝到服务器上,再部署,就有点麻烦. 所以写了个批处理命令 ...
- 【Leafletjs】5.L.Control 自定义一个Control
L.Control 所有leaflet控制的基础类.继承自IControl接口. 你可以这样添加控件: control.addTo(map); // the same as map.addContro ...
- DirectX HLSL相关基础
DirectX HLSL相关 顶点着色器可用软件顶点运算方式来模拟,即在创建设备时,将设备行为标记设定为: D3DCREATE_SOFTWARE_VERTEXPROCESSING 在记事本中编写着色器 ...
- Android SharedPreference的使用
在<Android 在内部存储读写文件>一文中,谈到了登录用户名和密码的方法,通过读取内存文件来实现,但是会出现问题,因为登录名和密码的形式通过username##password的形式, ...
- java 实现(代码) -- 水仙花数 + 杨辉三角形
/* 在控制台输出所有的“水仙花数” 水仙花:100-999 在以上数字范围内:这个数=个位*个位*个位+十位*十位*十位+百位*百位*百位 例如:xyz=x^3 +y^3 +z^3 怎么把三位数字拆 ...
- 2.3 CMMI2级——项目跟踪和控制(Project Monitoring and Control)
计划不是用来看的,是用来执行的.PP讲述了如何做计划,PMC讲述的就是如何跟踪计划的执行并在实际情况偏离计划时采取纠正行动. 我们先看看SG1,SG1讲述的是如何根据计划来跟踪计划的执行问题. SG1 ...
- (视频) 《快速创建网站》2.1 在Azure上创建网站及网站运行机制
现在让我们开始一天的建站之旅. 本文是<快速创建网站>系列的第2篇,如果你还没有看过之前的内容,建议你点击以下目录中的章节先阅读其他内容再回到本文. 访问本系列目录,请点击:http:// ...
- coursera机器学习-logistic回归,正则化
#对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...
- MFC MDI 获取当前视图
==================================声明================================== 本文原创,转载在正文中显要的注明作者和出处,并保证文章的完 ...