HDU 4735 Little Wish~ lyrical step~(DLX搜索)(2013 ACM/ICPC Asia Regional Chengdu Online)
Description
Input
Output
题目大意:一棵树上有n个结点,每个结点有一个男生或者一个妹纸,每条边有一个距离,问最少交换多少个人,使得妹纸在距离D内至少有一个男生。。。
思路:换句话说,这题可以理解为:交换多少个0或1,使得每个结点在D的距离内有一个1(1的男孩纸)。
那么用DLX搜索,每一列代表一个点。每一行代表一个点,每行的结点为这个点为1可以保护的所有点(包括自己)。
然后套DLX。
加入两个剪枝:搜索到的交换若大于当前答案,则剪枝。在每一层作一个乐观估计,估计最少还需要选出多少个点,若大于点为1的点数,则剪枝。
这题正解大概为DP。我不会。
代码(1171MS):
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std; const int MAXN = ;
const int MAXC = MAXN;
const int MAXR = MAXN;
const int MAXP = MAXR * MAXN + MAXC; int boy[MAXN];
int mat[MAXN][MAXN];
int n, D, boys; struct DLX {
int n, sz;//列数,结点总数
int sum[MAXC];//每列拥有的结点数
int row[MAXP], col[MAXP];//结点所在的行和列
int left[MAXP], right[MAXP], up[MAXP], down[MAXP];//十字链表
int ans, anst[MAXR]; void init(int nn) {
n = nn;
for(int i = ; i <= n; ++i) {
up[i] = down[i] = i;
left[i] = i - ; right[i] = i + ;
col[i] = i;
}
right[n] = ; left[] = n;
sz = n + ;
memset(sum, , sizeof(sum));
} void add_row(int r, vector<int> &columns) {
int first = sz;
for(int i = , len = columns.size(); i < len; ++i) {
int c = columns[i];
left[sz] = sz - ; right[sz] = sz + ; down[sz] = c; up[sz] = up[c];
down[up[c]] = sz; up[c] = sz;
row[sz] = r; col[sz] = c;
++sum[c]; ++sz;
}
right[sz - ] = first; left[first] = sz - ;
} void remove(int c) {
for(int i = down[c]; i != c; i = down[i]) {
left[right[i]] = left[i];
right[left[i]] = right[i];
}
} void restore(int c) {
for(int i = down[c]; i != c; i = down[i]) {
left[right[i]] = i;
right[left[i]] = i;
}
} bool vis[MAXC]; int A() {
memset(vis, , sizeof(vis));
int ret = ;
for(int i = right[]; i != ; i = right[i]) if(!vis[i]) {
++ret;
for(int j = down[i]; j != i; j = down[j]) {
for(int k = right[j]; k != j; k = right[k]) vis[col[k]] = true;
}
}
return ret;
} void dfs(int dep) {
if(dep + A() > boys) return ;
int tmp = ;
for(int i = ; i < dep; ++i) tmp += boy[anst[i]];
if(dep - tmp >= ans) return ;
if(right[] == ) {
ans = dep - tmp;
return ;
}
int c = right[];
for(int i = right[]; i != ; i = right[i]) if(sum[i] < sum[c]) c = i;
for(int i = down[c]; i != c; i = down[i]) {
anst[dep] = row[i];
remove(i);
for(int j = right[i]; j != i; j = right[j]) remove(j);
dfs(dep + );
for(int j = left[i]; j != i; j = left[j]) restore(j);
restore(i);
}
} bool solve() {
ans = n + ;
dfs();
return ans != n + ;
}
} S; void floyd() {
for(int k = ; k <= n; ++k)
for(int i = ; i <= n; ++i) if(mat[i][k] <= D)
for(int j = ; j <= n; ++j) if(mat[k][j] <= D)
mat[i][j] = min(mat[i][j], mat[i][k] + mat[k][j]);
} int main() {
int T; scanf("%d", &T);
for(int t = ; t <= T; ++t) {
scanf("%d%d", &n, &D);
memset(mat, 0x3f, sizeof(mat));
boys = ;
for(int i = ; i <= n; ++i) scanf("%d", &boy[i]), boys += boy[i];
for(int i = ; i < n; ++i) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
mat[u][v] = mat[v][u] = c;
}
for(int i = ; i <= n; ++i) mat[i][i] = ;
floyd();
S.init(n);
for(int i = ; i <= n; ++i) {
vector<int> columns;
for(int j = ; j <= n; ++j) if(mat[i][j] <= D) columns.push_back(j);
S.add_row(i, columns);
}
bool flag = S.solve();
printf("Case #%d: ", t);
if(flag) printf("%d\n", S.ans);
else puts("-1");
}
}
HDU 4735 Little Wish~ lyrical step~(DLX搜索)(2013 ACM/ICPC Asia Regional Chengdu Online)的更多相关文章
- HDU 4729 An Easy Problem for Elfness(主席树)(2013 ACM/ICPC Asia Regional Chengdu Online)
Problem Description Pfctgeorge is totally a tall rich and handsome guy. He plans to build a huge wat ...
- HDU 4747 Mex(线段树)(2013 ACM/ICPC Asia Regional Hangzhou Online)
Problem Description Mex is a function on a set of integers, which is universally used for impartial ...
- HDU 4291 A Short problem(2012 ACM/ICPC Asia Regional Chengdu Online)
HDU 4291 A Short problem(2012 ACM/ICPC Asia Regional Chengdu Online) 题目链接http://acm.hdu.edu.cn/showp ...
- HDU 5874 Friends and Enemies 【构造】 (2016 ACM/ICPC Asia Regional Dalian Online)
Friends and Enemies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- HDU 4063 Aircraft(计算几何)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4063 Description You are playing a flying game. In th ...
- HDU 4031 Attack(离线+线段树)(The 36th ACM/ICPC Asia Regional Chengdu Site —— Online Contest)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4031 Problem Description Today is the 10th Annual of ...
- HDU 4749 Parade Show 2013 ACM/ICPC Asia Regional Nanjing Online
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4749 题目大意:给一个原序列N,再给出一个序列M,问从N中一共可以找出多少个长度为m的序列,序列中的数 ...
- [2013 ACM/ICPC Asia Regional Nanjing Online C][hdu 4750]Count The Pairs(kruskal + 二分)
http://acm.hdu.edu.cn/showproblem.php?pid=4750 题意: 定义f(u,v)为u到v每条路径上的最大边的最小值..现在有一些询问..问f(u,v)>=t ...
- HDU 4751 Divide Groups 2013 ACM/ICPC Asia Regional Nanjing Online
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4751 题目大意:判断一堆人能否分成两组,组内人都互相认识. 解题思路:如果两个人不是相互认识,该两人之 ...
随机推荐
- 面向对象编程——class继承
在上面的章节中我们看到了JavaScript的对象模型是基于原型实现的.特点是简单,缺点是理解起来比传统类-实例模型要困难,最大的缺点是继承的实现需要编写大量代码,并且需要正确实现原型链. 新的关键字 ...
- 与JSON相关的问题
1.JSON.stringify 与 JSON.parse 相关的问题 JSON.stringify 把字符串转化为字符串,JSON.parse把字符串转化为JSON格式 会出现的问题Unexpect ...
- Vue组件通讯黑科技
Vue组件通讯 组件可谓是 Vue框架的最有特色之一, 可以将一大块拆分为小零件最后组装起来.这样的好处易于维护.扩展和复用等. 提到 Vue的组件, 相必大家对Vue组件之间的数据流并不陌生.最常规 ...
- HTML中footer固定在页面底部的若干种方法
<div class="header"><div class="main"></div></div> <d ...
- (暴力碾标算)NOIP模拟赛 宗教仪式
题意: 一个模式串,一个文本串,现定义最大失配值为k 求文本中最大失配值<=k的长度为len(模式串)的字串个数 失配值=当前字串中与模式串不同的字符个数 思路: 暴力,加一个跳出剪枝,居然过了 ...
- harbor中碰到的问题
harbor部署整体比较简单,但是就是这么简单的东西稍微改变点配置文件就会有不小的问题 1.问题1 部署harbor1.6发现web界面删除的镜像在push一遍上去后,镜像大小为0 且无法删除,这个问 ...
- php判断某个数是素数的3种方法
什么是素数? 质数又称素数.一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数:否则称为合数.(注:1不是素数.) 方法一: 基本方法,——计数方法. $num = 7; $n = ...
- 【tp5.1】微信公众号授权登录及获取信息录入数据库
微信公众号开发文档链接:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432 微信公众号授权登录分为两种: 1.以 ...
- 自定义控件,继承自 ListView
public class MyListView extends ListView { /** * 如果在xml中创建并设置了style,就会调用三个参数的. * * @param context * ...
- Windows使用Node.js自动生成Vue.js模版环境部署步骤-----记录
node.js官网下载并安装node 进入node文档目录下,运行cmd 输入 node -v 查看node版本 出现表示安装完成 输入 npm -v 显示npm版本信息 安装cnpm 输入 npm ...