hdu4848 DFS 暴搜+ 强剪枝
生活随笔
收集整理的這篇文章主要介紹了
hdu4848 DFS 暴搜+ 强剪枝
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? 給你一個圖,然后問你從1出發遍歷所有的點的距離和是多少,這里的距離和是每一個點到1的距離的總和,不是選擇一條遍歷所有點的路徑的總長度,時間限制是 8000ms。
思路:
? ? ? 給你一個圖,然后問你從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; }
總結
以上是生活随笔為你收集整理的hdu4848 DFS 暴搜+ 强剪枝的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu4849 最短路
- 下一篇: hdu4847 水题