hdu 4848 搜索+剪枝 2014西安邀请赛
http://acm.hdu.edu.cn/showproblem.php?pid=4848
比赛的时候我甚至没看这道题,事实上不难....
可是说实话,如今对题意还是理解不太好......
犯的错误:
1、floy循环次序写错,
2、搜索的时候。应该先推断i是不是能够搜(就是可不可能产生解)。然后标记vis[i]=1。我二逼的先标记vis[i]=1,然后推断i是不是可搜,这样肯定会导致有些时候,cnt!=n
我的剪枝方法(2546MS AC):
搜下一个结点之前。确保时间小于全部的未訪问的结点的Deadline
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std; #define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)
const ll ll_INF = ((ull)(-1))>>1;
const double EPS = 1e-8;
const int INF = 1e9+7;
const int MAXN = 50; int n;
int mat[MAXN][MAXN];
int dis[MAXN][MAXN];
int dead[MAXN];
void floy()
{
repe(k,1,n)
for(int i=1;i<=n;i++)
repe(j,1,n) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
int ans;
int vis[MAXN]; void dfs(int u, int t, int cnt,int tmp)
{
if(dead[u]<t || tmp>ans)return;
if(cnt == n)
{
ans=min(ans,tmp);
return;
}
for(int i=2;i<=n;i++)
if(!vis[i] && dead[i]>=t+dis[u][i])
{
int flag=0;
for(int j=2;j<=n;j++)
if(!vis[j] && t+dis[u][i]>dead[j] && i!=j)
flag=1;
if(flag)continue;
vis[i]=1;
dfs(i,t+dis[u][i],cnt+1,tmp+dis[u][i]*(n-cnt));
vis[i]=0;
}
} int main()
{
//IN("hdu4848.txt");
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&mat[i][j]),dis[i][j]=mat[i][j];
floy();
dead[1]=INF;
repe(i,2,n)
scanf("%d",&dead[i]);
ans=INF;
CL(vis,0);
vis[1]=1;
dfs(1,0,1,0);
if(ans == INF)printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
网上的方法:(359ms AC)
事实上剪枝思路跟我一样,可是比我的更好
倘若搜到当前结点,检查全部的未訪问的结点,假设不管以哪个未訪问结点为起点都不可能得到解,直接返回,相当于比我少遍历一层并且少了非常多反复
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std; #define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)
const ll ll_INF = ((ull)(-1))>>1;
const double EPS = 1e-8;
const int INF = 1e9+7;
const int MAXN = 50; int n;
int mat[MAXN][MAXN];
int dis[MAXN][MAXN];
int dead[MAXN]; void floy()
{
repe(k,1,n)
for(int i=1;i<=n;i++)
repe(j,1,n) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
int ans;
int vis[MAXN]; void dfs(int u, int t, int cnt,int tmp)
{
if(dead[u]<t || tmp>ans)return;
if(cnt == n)
{
ans=min(ans,tmp);
return;
}
for(int i=2;i<=n;i++)
if(!vis[i] && t+dis[u][i]>dead[i])
return;
for(int i=2;i<=n;i++)
if(!vis[i] && dead[i]>=t+dis[u][i])
{
vis[i]=1;
dfs(i,t+dis[u][i],cnt+1,tmp+dis[u][i]*(n-cnt));
vis[i]=0;
}
} int main()
{
//IN("hdu4848.txt");
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&mat[i][j]),dis[i][j]=mat[i][j];
floy();
dead[1]=INF;
repe(i,2,n)
scanf("%d",&dead[i]);
ans=INF;
CL(vis,0);
vis[1]=1;
dfs(1,0,1,0);
if(ans == INF)printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
hdu 4848 搜索+剪枝 2014西安邀请赛的更多相关文章
- hdu 5887 搜索+剪枝
Herbs Gathering Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- poj 1198 hdu 1401 搜索+剪枝 Solitaire
写到一半才发现能够用双向搜索4层来写,但已经不愿意改了,干脆暴搜+剪枝水过去算了. 想到一个非常水的剪枝,h函数为 当前点到终点4个点的最短距离加起来除以2.由于最多一步走2格,然后在HDU上T了, ...
- hdu 6196 搜索+剪枝
Today, Bob plays with a child. There is a row of n numbers. One can takes a number from the left sid ...
- hdu 5113(2014北京—搜索+剪枝)
题意:有N*M的棋盘,用K种颜色去染,要求相邻块不能同色.已知每种颜色要染的块数,问能不能染,如果能,输出任一种染法. 最开始dfs失败了- -,优先搜索一行,搜完后进入下一列,超时.本来以为搜索不行 ...
- hdu 5469 Antonidas(树的分治+字符串hashOR搜索+剪枝)
题目链接:hdu 5469 Antonidas 题意: 给你一颗树,每个节点有一个字符,现在给你一个字符串S,问你是否能在树上找到两个节点u,v,使得u到v的最短路径构成的字符串恰好为S. 题解: 这 ...
- 计蒜客 39272.Tree-树链剖分(点权)+带修改区间异或和 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest E.) 2019ICPC西安邀请赛现场赛重现赛
Tree Ming and Hong are playing a simple game called nim game. They have nn piles of stones numbered ...
- NOIP2015 斗地主(搜索+剪枝)
4325: NOIP2015 斗地主 Time Limit: 30 Sec Memory Limit: 1024 MBSubmit: 270 Solved: 192[Submit][Status] ...
- hdu 5016 点分治(2014 ACM/ICPC Asia Regional Xi'an Online)
Mart Master II Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- hdu 5636 搜索 BestCoder Round #74 (div.2)
Shortest Path Accepts: 40 Submissions: 610 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: ...
随机推荐
- MYSQL数据库命名与其设计规范
你是否对获得MYSQL数据库命名与其设计规范 的实际操作感到十分头疼?如果是这样子的话,以下的文章将会给你相应的解决方案,以下的文章主要是介绍获得MYSQL数据库命名与其设计规范 的方案,以下就是相关 ...
- maven发布时在不同的环境使用不同的配置文件
在开发时,不同的环境总会使用到不同的配置.如本地,测试,预发布,发布等环境,像数据库这些都要使用到不同的配置.如果手动改的话肯定会十分的麻烦. 还好maven提供的功能能够帮我们解决这个问题. 我们通 ...
- 关于JavaScript对象的键和值
一个JavaScript对象由键和值组成. 当一个给定键的值被设置为一个字符串.布尔值.数字.数组或对象时,我们把这个键称为属性. 当把键设置为函数时,我们把它叫做方法.
- Java实现多线程下载
package cn.test.DownLoad; import java.io.File; import java.io.InputStream; import java.io.RandomAcce ...
- QT5-控件-QSpinBox和QDoubleSpinBox(用于通过控件调整整数和小数)
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSpinBox> #in ...
- Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结【转载】
详细解读Jquery各Ajax函数:$.get(),$.post(),$.ajax(),$.getJSON() 一,$.get(url,[data],[callback]) 说明:url为请求地址,d ...
- 文字列表无缝向上滚动JavaScript代码
<!DOCTYPE html> <html> <head> <meta charset=utf-> <title>文字列表无缝向上滚动Jav ...
- Nginx源码研究三:Epoll在NGINX中的使用
Web服务器在面对高并发的情况下,网络的IO一般选择IO复用,像apache选择的Select/poll.Nginx在linux 2.6后选择Epoll做网路IO,提高了WEB服务的并发能力. 在本章 ...
- oldboy第十三天学习
1.现在给我的感觉是,python终于入门了开始越学越简单了.变得更好理解了. 一.memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它 ...
- iOS中常用的四种数据持久化方法简介
iOS中常用的四种数据持久化方法简介 iOS中的数据持久化方式,基本上有以下四种:属性列表.对象归档.SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 ...