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. DirectX Graphics Infrastructure (DXGI) 全屏设置相关问题

    原文地址: https://msdn.microsoft.com/en-us/library/windows/desktop/ee417025(v=vs.85).aspx 未完待续... DXGI是在 ...

  2. WPF画N角芒星,正N角星

    计算顶部三角形坐标方法: /// <summary> /// 获取顶三角形坐标 /// </summary> /// <param name="r"& ...

  3. wsdl和wadl区别

    [转]http://blog.csdn.net/liuxiao723846/article/details/51611183 1.Java开发WebService最重要的两个规范: JSR-224 ( ...

  4. oracle双机热备概念

    1. 双机热备概述      双机热备有两种实现模式,一种是基于共享的存储设备的方式,另一种是没有共享的存储设备的方式,一般称为纯软件方式.      基于存储共享的双机热备是双机热备的最标准方案. ...

  5. CSS定位与浮动

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

  6. Axure矩形边框重合边框变成双倍宽度解决办法

    选中两个矩形,菜单栏选择项目——项目设置——边界对齐(选择中心边界沿形状的边缘或者内边界对齐.将外边界对齐改为内边界对齐),即可去掉重合效果

  7. 网络请求时 返回 App Transport Security has blocked a cleartext HTTP

    如上图,是因为 Xcode7 没有对 plist 进行 http 请求的配置  所致 这时需要  加上上面的plist的红框中 的内容  并且 设置 为 yes  如下图

  8. iOS推送 再备

    这是一篇编译的文章,内容均出自Parse.com的iOS开发教程,同时作者还提供了视频讲解.本文将带领开发者一步一步向着iOS推送通知的深处探寻,掌握如何配置iOS推送通知的奥义. 介绍一点点背景资料 ...

  9. Android json操作之取得一个对象

    1:服务端返回的json数据格式如下: {"id":"1001","name":"zhangsan","sco ...

  10. Windows内存小结(有好多图,比较清楚)

    以前写过一篇理解程序内存, 当时主要是针对用户态,下面再稍微深入一点: 我们以32位程序为例(不启用AWE), 总共4G虚拟空间,其中低2G属于用户态, 高2G属于操作系统内核, 每个程序都有自己的低 ...