hdu4848 DFS 暴搜+ 强剪枝
2024-08-24 12:53:24
题意:
给你一个图,然后问你从1出发遍历所有的点的距离和是多少,这里的距离和是每一个点到1的距离的总和,不是选择一条遍历所有点的路径的总长度,时间限制是 8000ms。
思路:
一开始理解错了,以为是选择一条路径能遍历所有点的路径的总长度,如果是这样可以有两种方法一个就是暴搜时间复杂度n!(不可以),另一个是dp,开dp[i][j] i是状态,j是点(也不可以,状态太大了),所以就蛋疼了,后来发现自己读错题了,what's all,哎! 这个题目可以直接暴搜,有两个剪纸,一个就是根据时间剪纸,每一步必须保证后面的所有的时间都来得及,另一个就是如果当前值比答案还大,那么就直接return.
#include<stdio.h>
#include<string.h>
int time[33] ,mark[33];
int dis[33][33];
int n ,ans; int minn(int x ,int y)
{
return x < y ? x : y;
} void Floyd(int n)
{
for(int k = 1 ;k <= n ;k ++)
for(int i = 1 ;i <= n ;i ++)
for(int j = 1 ;j <= n ;j ++)
dis[i][j] = minn(dis[i][j] ,dis[i][k] + dis[k][j]);
} void DFS(int frm ,int s ,int len ,int ge ,int sum)
{
if(s == n)
{
ans = minn(ans ,sum);
return ;
}
if(sum > ans) return;
for(int i = 2 ;i <= n ;i ++)
if(!mark[i] && len + dis[frm][i] > time[i])
return;
for(int i = 2 ;i <= n ;i ++)
{
if(!mark[i])
{
mark[i] = 1;
DFS(i ,s + 1 ,len + dis[frm][i] ,ge - 1 ,sum + dis[frm][i] * ge);
mark[i] = 0;
}
}
} int main ()
{
int i ,j;
while(~scanf("%d" ,&n))
{
for(i = 1 ;i <= n ;i ++)
for(j = 1 ;j <= n ;j ++)
scanf("%d" ,&dis[i][j]);
for(i = 2 ;i <= n ;i ++)
scanf("%d" ,&time[i]);
Floyd(n);
ans = 1000000000;
memset(mark ,0 ,sizeof(mark));
DFS(1 ,1 ,0 ,n - 1 ,0);
ans == 1000000000 ? puts("-1") : printf("%d\n" ,ans);
}
return 0;
}
最新文章
- VC++动态链接库(DLL)编程深入浅出(zz)
- IEEE802是一个局域网标准系列
- google guava 基本工具
- linux动态库加载的秘密
- avalon.js实践 svg地图配置工具
- cv2.imread BGR模式
- asp.net MVC 模拟实现与源码分析
- HDU 4403 A very hard Aoshu problem(DFS)
- SQL 课程 子查询
- 初识Java,猜字游戏
- 什么是CSS
- JAVA学习笔记(4)—— 排序算法
- ubuntu16.04 pycharm的安装
- .net分布式系统架构的思路
- DRF之接口文档以及Xadmin
- 11.14java课堂测试
- Android开发——Android进程保活招式大全
- Spark的机器学习算法mlib的例子运行
- 2017-2018-1 20155220 《信息安全系统设计基础》课下实践——实现mypwd
- ny8 一种排序 sort