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西安邀请赛的更多相关文章

  1. hdu 5887 搜索+剪枝

    Herbs Gathering Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  2. poj 1198 hdu 1401 搜索+剪枝 Solitaire

    写到一半才发现能够用双向搜索4层来写,但已经不愿意改了,干脆暴搜+剪枝水过去算了. 想到一个非常水的剪枝,h函数为  当前点到终点4个点的最短距离加起来除以2.由于最多一步走2格,然后在HDU上T了, ...

  3. hdu 6196 搜索+剪枝

    Today, Bob plays with a child. There is a row of n numbers. One can takes a number from the left sid ...

  4. hdu 5113(2014北京—搜索+剪枝)

    题意:有N*M的棋盘,用K种颜色去染,要求相邻块不能同色.已知每种颜色要染的块数,问能不能染,如果能,输出任一种染法. 最开始dfs失败了- -,优先搜索一行,搜完后进入下一列,超时.本来以为搜索不行 ...

  5. hdu 5469 Antonidas(树的分治+字符串hashOR搜索+剪枝)

    题目链接:hdu 5469 Antonidas 题意: 给你一颗树,每个节点有一个字符,现在给你一个字符串S,问你是否能在树上找到两个节点u,v,使得u到v的最短路径构成的字符串恰好为S. 题解: 这 ...

  6. 计蒜客 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  ...

  7. NOIP2015 斗地主(搜索+剪枝)

    4325: NOIP2015 斗地主 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 270  Solved: 192[Submit][Status] ...

  8. 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 ...

  9. hdu 5636 搜索 BestCoder Round #74 (div.2)

    Shortest Path  Accepts: 40  Submissions: 610  Time Limit: 4000/2000 MS (Java/Others)  Memory Limit: ...

随机推荐

  1. 关于IIS部署成功后,局域网其他用户无法访问的问题解决方法

    关于win7部署iis后,局域网的其他用户不能访问的问题.   在win7系统中,部署好iis后,自己本地可以发布和预览.但在局域网中的其他用户不可以访问.下面说一下这个原因. 这是因为win7自带的 ...

  2. OD: DEP & Ret2Libc

    Data Execution Prevention,数据执行保护,专门用来弥补计算机对数据和代码混淆这一天然缺陷. DEP 的原理是将数据所在的内存页(默认的堆.各种堆栈页.内存池页)标记为不可执行, ...

  3. android系统360浏览器使用append动态添加元素出现黑色错乱背景

    去掉样式 backface-visibility:hidden;

  4. shell编程备忘

    1.脚本存放目录 workspace="$(cd "$(dirname "$0")"; pwd)" 2.输出  其中 command 代表指 ...

  5. php long time(1)

    好久好久没有发表新的文章了,主要是懒得在这里写,都记在记事本上,所得都是自己理解的情况下写的,如今借此闲暇记录下来,:::: ****************PHP****************** ...

  6. 如何在CentOS 7上修改主机名

    如何在CentOS 7上修改主机名 在CentOS中,有三种定义的主机名:静态的(static),瞬态的(transient),和灵活的(pretty).“静态”主机名也称为内核主机名,是系统在启动时 ...

  7. 用POP动画引擎实现弹簧动画(POPSpringAnimation)

    效果图: #import "ViewController.h" #import <POP.h> @interface ViewController () @proper ...

  8. nodejs+express 4.x笔记

    4.x与3.x变化比较大,包括安装以及api 一:安装express4.x 1. npm install express -g //express modules2. npm install expr ...

  9. CSS定位与浮动

    定位的基本思想很简单,它允许你定义元素框相对于其正常位置应该出现的位置,或者相对于父元素.另一个元素甚至浏览器窗口本身的位置.显然,这个功能非常强大,也很让人吃惊.要知道,用户代理对 CSS2 中定位 ...

  10. dede 日期的所有格式

    [field:pubdate function=strftime('%d',@me)/] 日 [field:pubdate function=strftime('%d日',@me)/] - [fiel ...