• HDU4848 Wow! Such Conquering! —— dfs + 剪枝


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4848


    题解: 一开始读错题目。以为每个点只能访问一遍。其实只要每个点都有被访问就可以了。

    首先是用弗洛伊德算法求出每两点之间的最短路。然后再用dfs搜索。注意剪枝,否则会超时。


    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <string>
     6 #include <vector>
     7 #include <map>
     8 #include <set>
     9 #include <queue>
    10 #include <sstream>
    11 #include <algorithm>
    12 using namespace std;
    13 #define pb push_back
    14 #define mp make_pair
    15 #define ms(a, b)  memset((a), (b), sizeof(a))
    16 #define eps 0.0000001
    17 typedef long long LL;
    18 const int INF = 2e9;
    19 const LL LNF = 9e18;
    20 const int maxn = 2000000+10;
    21 const int mod = 1e9+7;
    22 
    23 int dis[35][35],deadline[35];
    24 int vis[35];
    25 int n,ans;
    26 
    27 void dfs(int u, int cnt, int time, int sum)
    28 {
    29     if(cnt==n)
    30     {
    31         ans = min(ans,sum);
    32         return;
    33     }
    34 
    35     //剪枝:
    36     if(sum+time*(n-cnt)>=ans) return;
    37     for(int i = 2; i<=n; i++)
    38         if(!vis[i] && time+dis[u][i]>deadline[i]) return;
    39 
    40     for(int i = 2; i<=n; i++)
    41     {
    42         if(!vis[i])
    43         {
    44             vis[i] = 1;
    45             dfs(i,cnt+1,time+dis[u][i], sum+time+dis[u][i]);
    46             vis[i] = 0;
    47         }
    48     }
    49 }
    50 
    51 void solve()
    52 {
    53     for(int i = 1; i<=n; i++)
    54         for(int j = 1; j<=n; j++)
    55             scanf("%d",&dis[i][j]);
    56 
    57     for(int i = 2; i<=n; i++)
    58         scanf("%d",&deadline[i]);
    59 
    60     for(int k = 1; k<=n; k++)//弗洛伊德算法
    61         for(int i = 1; i<=n; i++)
    62             for(int j = 1; j<=n; j++)
    63                 dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]);
    64 
    65     ans = INF;
    66     ms(vis,0);
    67 
    68     dfs(1,1,0,0);
    69     if(ans!=INF)
    70         printf("%d
    ",ans);
    71     else
    72         puts("-1");
    73 }
    74 
    75 int main()
    76 {
    77     while(scanf("%d",&n)!=EOF){
    78         solve();
    79     }
    80     return 0;
    81 }
    View Code


  • 相关阅读:
    Linux 相关scsi命令
    存储
    Multipath多路径冗余全解析
    Oracle中alter system命令参数之scope
    scipy安装失败
    font
    查看端口占用
    oracle参数优化
    组播
    sql给整数补零
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538715.html
Copyright © 2020-2023  润新知