题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5352

看题看得心好累。

题目大意:

给出 n 个点,依次执行 m 次操作:输入“1 x”时,表示将与 x 连通的点全部修复;输入“2 x y”,表示在 x 与 y 之间加一条边;输入“3 x y”,表示删除 x 与 y 之间的边。题目确保不会与重边并且操作合法。

题目会给出 k,要求每次修复的的点的数目小于等于k。

问:怎样执行操作1,使得令修复点数最多的同时,令每次执行操作1所修复的点的数目所构成的数列字典序最小。(可以令某次操作无效,或者说令其修复的点数为0)

解题思路:

二分图最大匹配、拆点。

(我反正是看题解才弄明白的。。)

具体实现过程:

首先我们知道二分图最大匹配的用途。在这道题中,左侧点对应于每次操作1,右侧点即所有的点。然后边对应于——每次操作1修复的点 和 与之相连通的点 之间的边。则寻找最大匹配即为寻找在所有操作下所能得到的最大匹配数。

显然操作2与操作3都是为操作1而服务的,直接相关于与操作1所操作的点所连通的点(好累赘。。)。每次执行操作1时,记录与该点相连通的所有点,并给该点与所连通的点建边。这里注意:拆点。将每个点都拆成 k 个点。这样的话,每个操作所得的最大匹配数<=k,即每个操作所修复的点的个数<=k。

图已建好,跑一遍匈牙利算法就可以了(不考虑字典序的情况下)。

要考虑字典序的话,由匈牙利算法的特性易知,则从最后一次操作往前跑匈牙利算法即可。

容易思维卡壳的是,对于每次操作1,与点 x 相连通的点<=k时,全部都选了不就可以了吗等等。

需要注意的是,当下操作得到最大值不一定使得最后的最优值。即局部最优解未必能得到全局最优解,所以才需要用二分图最大匹配算法。

注意对maxn的大小设定。

然后是,这个做法最后做出来是700ms左右,不太理想。据说还可以用最大流和最小费用最大流做。

考虑不换算法的优化的话,首先是用数组模拟邻接表,因为用vector的push_back和clear操作耗时颇大。尤其在初始化调用g[i].clear()的时候,i的边界的设定如果过大的话会导致TLE。具体会快多少不好说。

然后是匈牙利算法换成bfs实现。晚点再写一下看能快多少。

这是上次华师校赛后第二次碰到二分图最大匹配的题,充分体现的该算法理解的不足。模板题和应用题毕竟两回事。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 555
int n,m,k,T,op,a,b,c,tot,ans,ary[maxn],pic[maxn][maxn];
vector<int>g[maxn*maxn];
int con[maxn],vis[maxn],con_tot[maxn],divp;
void init(){
memset(pic,,sizeof(pic));
memset(ary,,sizeof(ary));
memset(con,,sizeof(con));
divp=ans=tot=;
for(int i=;i<=n*k;i++) g[i].clear();
}
void find_con(int u){
vis[u]=;
con_tot[tot++]=u;
for(int i=;i<=n;i++) if(!vis[i]&&pic[u][i])
find_con(i);
}
int dfs(int u){
for(int i=;i<g[u].size();i++){
int v=g[u][i];
if(!vis[v]){
vis[v]=;
if(!con[v]||dfs(con[v])){
con[v]=u;
return ;
}
}
}
return ;
}
void solve(){
for(int i=divp-;i>=;i--){
for(int j=i*k,lim=(i+)*k;j<lim;j++){
memset(vis,,sizeof(vis));
if(dfs(j)){
ans++;
ary[i]++;
}
}
}
}
int main(){
//freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&k);
init();
for(int i=;i<m;i++){
scanf("%d",&op);
if(op==){
scanf("%d",&a);
tot=;
memset(vis,,sizeof(vis));
find_con(a);
for(int j=;j<tot;j++){
for(int t=k*divp,lim=k*(divp+);t<lim;t++)
g[t].push_back(con_tot[j]);
}
divp++;
}
else if(op==){
scanf("%d%d",&a,&b);
pic[a][b]=pic[b][a]=;
}
else{
scanf("%d",&c);
for(int j=;j<c;j++){
scanf("%d%d",&a,&b);
pic[a][b]=pic[b][a]=;
}
}
}
solve();
printf("%d\n",ans);
for(int i=;i<divp;i++)
printf("%d%c",ary[i],i==divp-?'\n':' ');
}
return ;
}

2015 多校赛 第五场 1010 (hdu 5352)的更多相关文章

  1. 2015 多校赛 第五场 1006 (hdu 5348)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5348 题目大意:给出一幅无向图,问是否存在一种方案,使得给每条边赋予方向后,每个点的入度与出度之差小于 ...

  2. 2015 多校赛 第四场 1010 (hdu 5336)

    Problem Description XYZ is playing an interesting game called "drops". It is played on a r ...

  3. 2015 多校赛 第七场 1011 (hdu 5379)

    题意:给定一棵树,树上有 n 个节点.问有多少种方案,使得在每个节点上依次放置数 1~n 后,每个节点的儿子节点上的数连续(比如 1 为根,有1-2,1-3,1-4,则令2,3,4上的数连续),每个子 ...

  4. 2015 多校赛 第四场 1009 (hdu 5335)

    Problem Description In an n∗m maze, the right-bottom corner is the exit (position (n,m) is the exit) ...

  5. 2015 多校赛 第三场 1002 (hdu 5317)

    Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more and more i ...

  6. 2014多校第五场1010 || HDU 4920 Matrix multiplication(矩阵乘法优化)

    题目链接 题意 : 给你两个n*n的矩阵,然后两个相乘得出结果是多少. 思路 :一开始因为知道会超时所以没敢用最普通的方法做,所以一直在想要怎么处理,没想到鹏哥告诉我们后台数据是随机跑的,所以极端数据 ...

  7. NOI.AC NOIP模拟赛 第五场 游记

    NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...

  8. 【杂题总汇】HDU多校赛第十场 Videos

    [HDU2018多校赛第十场]Videos 最后一场比赛也结束了…… +HDU传送门+ ◇ 题目 <简要翻译> 有n个人以及m部电影,每个人都有一个快乐值.每场电影都有它的开始.结束时间和 ...

  9. hdu5379||2015多校联合第7场1011 树形统计

    pid=5379">http://acm.hdu.edu.cn/showproblem.php? pid=5379 Problem Description Little sun is ...

随机推荐

  1. vue02 过滤器、计算和侦听属性、vue对象的生命周期、阻止事件冒泡和刷新页面

    3. Vue对象提供的属性功能 3.1 过滤器 过滤器,就是vue允许开发者自定义的文本格式化函数,可以使用在两个地方:输出内容和操作数据中. 定义过滤器的方式有两种. 3.1.1 使用Vue.fil ...

  2. JS对象中,在原型链上找到属性后 最终将值拷贝给原对象 而不是引用

    遇到一个面试题 要求写一个函数A,每次进行new操作时候能输出2,3,4,5... new A() // 输出2 new A() // 输出3 new A() // 输出4 function A() ...

  3. JS练习:定时弹出广告

    代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title ...

  4. 基本数据类型:布尔型(bool)和空值None

    一.布尔型(bool) 布尔类型很简单,就两个值 ,一个True(真),一个False(假), 主要用记逻辑判断: 一件事情成立就是True,不成立就是False,也可以将bool值归类为数字, 是因 ...

  5. Vue中数据的处理

    临时变量参数的存储 1.引用类型和值类型的差异,及存储 2.在项目中做的绑定值,首先v-model 存储到临时变量,同时把数据在提交到api之前,需要做处理,因为是引用类型的数据,在处理之前,会修改掉 ...

  6. Delphi 10.3.2最新消息

    官方已经发布消息,招内测人员了! https://www.barnsten.com/default/newsupdates/details?news_id=328 https://docs.googl ...

  7. Linux学习总结(3)——Linux实用工具

    1. Windows下同步Linux文件(Linux安装Samba和配置) 场景需求: 安装了Ubuntu在虚拟机上,但是代码编辑或者其它更多的操作的时候,还是习惯在windows下进行.如果wind ...

  8. (39.4) Spring Boot Shiro权限管理【从零开始学Spring Boot】

    在读此文章之前您还可能需要先了解: (39.1) Spring Boot Shiro权限管理[从零开始学Spring Boot] http://412887952-qq-com.iteye.com/b ...

  9. hdu 4862KM&最小费用最大流

    /*最小K路径覆盖的模型,用费用流或者KM算法解决, 构造二部图,X部有N*M个节点,源点向X部每个节点连一条边, 流量1,费用0,Y部有N*M个节点,每个节点向汇点连一条边,流量1, 费用0,如果X ...

  10. BZOJ1191 超级英雄Hero (匈牙利算法)

    直接跑匈牙利,注意到“只有当选手正确回答一道题后,才能进入下一题,否则就被淘汰”,一旦无法满足就直接退出. #include <cstdio> #include <algorithm ...