hdu 4848 Wow! Such Conquering! (暴搜+强剪枝)

Wow! Such Conquering!

Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 0    Accepted Submission(s): 0

Problem Description

   There are n Doge Planets in the Doge Space. The conqueror of Doge Space is Super Doge, who is going to inspect his Doge Army on all Doge Planets. The inspection starts from Doge Planet 1 where DOS (Doge Olympic Statue) was built. It takes Super Doge exactly Txy time to travel from Doge Planet x to Doge Planet y.
   With the ambition of conquering other spaces, he would like to visit all Doge Planets as soon as possible. More specifically, he would like to visit the Doge Planet x at the time no later than Deadlinex. He also wants the sum of all arrival time of each Doge Planet to be as small as possible. You can assume it takes so little time to inspect his Doge Army that we can ignore it.

Input

   There are multiple test cases. Please process till EOF.
   Each test case contains several lines. The first line of each test case contains one integer: n, as mentioned above, the number of Doge Planets. Then follow n lines, each contains n integers, where the y-th integer in the x-th line is Txy . Then follows a single line containing n - 1 integers: Deadline2 to Deadlinen.
   All numbers are guaranteed to be non-negative integers smaller than or equal to one million. n is guaranteed to be no less than 3 and no more than 30.

Output

   If some Deadlines can not be fulfilled, please output “-1” (which means the Super Doge will say “WOW! So Slow! Such delay! Much Anger! . . . ” , but you do not need to output it), else output the minimum sum of all arrival time to each Doge Planet.

Sample Input

4
0 3 8 6
4 0 7 4
7 5 0 2
6 9 3 0
30 8 30
4
0 2 3 3
2 0 3 3
2 3 0 3
2 3 3 0
2 3 3

Sample Output

36
-1

Explanation:
In case #1: The Super Doge travels to Doge Planet 2 at the time of 8 and to Doge Planet 3 at the time of 12, then to Doge Planet 4 at the time of 16. The minimum sum of all arrival time is 36.

题意:

有n个点(n<=30),从第一个点出发,要遍历完所有点,遍历每个点要在time[i]之前遍历,求到达每个点的距离之和。

感谢大牛 Sd.无心插柳and  在错觉中生活 提供的思路。

思路:

30个点,果断暴搜就行。根据time[i]剪枝,一个强剪枝就是走过一条边,还剩下num个点的话,答案是要加edge*num的,当前答案大于答案的时候剪枝就行了。

代码1:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define maxn 1005
#define MAXN 100005
#define mod 100000000
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;

int n,m,ans,tot;
int dist[35][35],time[35],bit[35];

void floyd()
{
    int i,j,k;
    for(k=0;k<n;k++)
    {
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
            }
        }
    }
}
void dfs(int u,int s,int cost,int sum,int num)
{
    if(sum>=ans) return ;
    if(s==tot)
    {
        ans=min(ans,sum);
        return ;
    }
    int i;
    for(i=1;i<n;i++)
    {
        if(s&bit[i]) continue ;
        if(cost+dist[u][i]>time[i]) return ;
    }
    for(i=1;i<n;i++)
    {
        if(s&bit[i]) continue ;
        dfs(i,s|bit[i],cost+dist[u][i],sum+dist[u][i]*num,num-1);
    }
}
int main()
{
   int i,j,t;
   for(i=0;i<=30;i++)
   {
       bit[i]=(1<<i);
   }
   while(~scanf("%d",&n))
   {
       for(i=0;i<n;i++)
       {
           for(j=0;j<n;j++)
           {
               scanf("%d",&dist[i][j]);
           }
       }
       for(i=1;i<n;i++)
       {
           scanf("%d",&time[i]);
       }
       tot=bit[n]-1;
       floyd();
       ans=INF;
       dfs(0,1,0,0,n-1);
       if(ans==INF) ans=-1;
       printf("%d\n",ans);
   }
}

顺便简单学习了一下双向链表的知识。

代码2:(搜索时用双向链表)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define maxn 1005
#define MAXN 100005
#define mod 100000000
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;

int n,m,ans,tot,len;
int dist[35][35],time[35],R[35],L[35];

void floyd()
{
    int i,j,k;
    for(k=1;k<=n;k++)
    {
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
            }
        }
    }
}
void dfs(int u,int cost,int sum,int num)
{
    for(int i=R[0];i;i=R[i])
    {
        if(cost+dist[u][i]>time[i]) return ;
    }
    if(sum>=ans) return ;
    R[L[u]]=R[u]; L[R[u]]=L[u];  // 删除u
    if(R[0]==0)
    {
        ans=min(ans,sum);
        R[L[u]]=L[R[u]]=u;
        return ;
    }
    for(int i=R[0];i;i=R[i])
    {
        dfs(i,cost+dist[u][i],sum+dist[u][i]*num,num-1);
    }
    R[L[u]]=L[R[u]]=u;  // 恢复u
}
int main()
{
   int i,j,t;
   while(~scanf("%d",&n))
   {
       for(i=1;i<=n;i++)
       {
           for(j=1;j<=n;j++)
           {
               scanf("%d",&dist[i][j]);
           }
       }
       for(i=2;i<=n;i++)
       {
           scanf("%d",&time[i]);
       }
       floyd();
       for(i=0;i<=n;i++)  // 初始化
       {
           R[i]=i+1; L[i]=i-1;
       }
       R[n]=0; L[0]=n;
       ans=INF;
       dfs(1,0,0,n-1);
       if(ans==INF) ans=-1;
       printf("%d\n",ans);
   }
}


hdu 4848 Wow! Such Conquering! (暴搜+强剪枝)

时间: 2024-08-02 06:58:53

hdu 4848 Wow! Such Conquering! (暴搜+强剪枝)的相关文章

hdu 4848 Wow! Such Conquering!

Wow! Such Conquering! Problem Description There are n Doge Planets in the Doge Space. The conqueror of Doge Space is Super Doge, who is going to inspect his Doge Army on all Doge Planets. The inspection starts from Doge Planet 1 where DOS (Doge Olymp

hdu 4400 离散化+二分+BFS(暴搜剪枝还超时的时候可以借鉴一下)

Mines Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1110    Accepted Submission(s): 280 Problem Description Terrorists put some mines in a crowded square recently. The police evacuate all peo

hdu1455 Sticks 深搜 强剪枝

Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6035    Accepted Submission(s): 1704 Problem Description George took sticks of the same length and cut them randomly until all parts becam

HDOJ 4848 Wow! Such Conquering!

dfs+减枝.... Wow! Such Conquering! Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 651    Accepted Submission(s): 195 Problem Description There are n Doge Planets in the Doge Space. The conquero

HDU 5961:传递(暴搜)

http://acm.hdu.edu.cn/showproblem.php?pid=5961 题意:中文题意.给出两个图,判断这个两个图是否都是传递的.注意一下传递的定义要看清,一开始没看清连样例都看不懂. 思路:点数很少,有了异或那题的暴力之后,这题继续试着爆搜了一下,也能过.主要存两个图,然后dfs的时候传入当前点的上一个点fa,如果 fa 和 下一个点 v 之间没有边相连,那么就不满足条件了. 1 #include <cstdio> 2 #include <cstring>

HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)

Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried despe

ROADS POJ - 1724 约束最短路 暴搜 加剪枝

http://poj.org/problem?id=1724 题意:最短路的模板,不过每条边加上一个费用,要求总费用不超过k 题解:不能用dijkstra ,直接暴力,dfs维护len和cost. 普通的剪枝:如果当前的cost大于k直接跳出,如果当前的len大于minlen(目前的最优解),跳出. 另一个剪枝:维护花费一定费用 到达某个点 的最短路minL[v][cost],如果当前的len大于L,则跳出. ac代码: #define _CRT_SECURE_NO_WARNINGS #incl

Hdu 4016 Magic Bitwise And Operation (暴搜 dfs)

题目大意: 在n个数中选取k个数,是他们的按位与最小. 思路分析: 开始往dp想,但是这道题是不满足子问题的. 当前的值最小,但是丢掉了和后面的1错开的最多的状态. 暴搜的剪枝: 1.与后面所有的树相与都比ans小,剪掉,因为越与越小. 2.先将所有的数排序,先取小的. 3.ans可以不断更新,不需要达到k的时候更新,原因和1相同. #include <cstdio> #include <iostream> #include <cstring> #include <

HDU 4848

http://acm.hdu.edu.cn/showproblem.php?pid=4848 题意:求遍历所有点的最小值(这个答案是加i点到起始点的距离,不是当前点到i的距离),必须在ti[i]前到达i点 题解:暴搜,剪枝是((当前值>ans)&&(当前点到未到点的时间加上起点到当前点的时间大于未到点的截止时间))则停止,遍历到n个点停止搜索,各点间的最短路用floyd处理 思考:用暴搜贼简单的一道题,难在勇于暴搜的那份勇气,比赛的时候我们根本没读这道题也没有什么好说的了 #incl