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 题目大意:判断一堆人能否分成两组,组内人都互相认识. 解题思路:如果两个人不是相互认识,该两人之 ...
随机推荐
- 解决div+img布局下img下端出现空白的bug
1.将图片转换为块级对象 即设置img为“display:block;”.在本例中添加一组CSS代码:“#sub img {display:block;}”. 2.设置图片的垂直对齐方式 即设置图片的 ...
- centos6: mysql+nginx+php
安装配置: mysql: http://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/ yum repolist enabled | grep mys ...
- Es6的那些事
现在看招聘网站上的要求,作为前端er~都要熟悉甚至精通(滑稽脸)es6,项目中也经常用,啥let,const,尤其是用react的同学,肯定对解构赋值不会陌生,今天逛淘宝前端的博客,看到一篇名为Es6 ...
- TCP协议与UDP协议
网络通信协议规定了网络通信时,数据必须采用的格式.常见的协议有TCP协议,UDP协议. TCP协议 :(Transmission Control Protocol)传输控制协议. TCP是一种面向连接 ...
- spring入门学习感悟
1:ioc:控制反转 控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是有外部容器负责创建和维护的(获取依赖对象的过程被反转了) 2:di:依赖注入,它是一种控制反转的一种实现方法,ioc容器 ...
- Linux mongodb安装、启动、运行
1.下载 wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.4.tgz 2.安装 tar -zxvf ...
- JavaScript实现快速排序(Quicksort)
目前,最常见的排序算法大概有七八种,其中"快速排序"(Quicksort)使用得最广泛,速度也较快.它是图灵奖得主 东尼·霍尔(C. A. R. Hoare)于1960时提出来的. ...
- #leetcode刷题之路5-最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1:输入: "babad"输出: "bab"注意: " ...
- 【Win10分区教程】
Win10怎么分区?如何为Win10硬盘分区? 注:本教程适用于Win7.Win8.Win8.1和Win10系 到了Windows10时代,TB级硬盘已经很普及了,那么在Win10系统下如何为这些大容 ...
- kali下添加用户和权限分配
1.添加用户 useradd -m test #-m的意思是创建用户的主目录 2.为用户test设置密码. passwd test 3.为添加的用户赋予权限(-a 添加 :-G 群组) 如果没有这一步 ...