初涉A*剪枝

挖坑防忘,天亮补题解。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>

#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long LL
#define _LL __int64
#define _INF 0x3f3f3f3f
#define Mod 1000000007

using namespace std;

const int MAXN = 100100;

struct N
{
    int u,v,w,next,ty;
}edge[2*MAXN];

int head[MAXN];

int Top;

void Link(int u,int v,int w,int ty)
{
    edge[Top].ty = ty;
    edge[Top].v = v;
    edge[Top].w = w;
    edge[Top].next = head[u];
    head[u] = Top++;
}

int ans[1010];

int w[1010][1010];

int H[1010];

struct Q
{
    int v,g,h,f;
    bool operator < (const Q &a) const
    {
        return a.f < f;
    }
};

void Init_H(int t)
{
    Q s,f;
    s.f = 0;
    s.v = t;

    memset(H,-1,sizeof(H));
    H[t] = 0;

    priority_queue<Q> q;
    q.push(s);

    while(q.empty() == false)
    {
        f = q.top();
        q.pop();

        H[f.v] = (H[f.v] == -1 ? f.f : H[f.v]);

        for(int p = head[f.v]; p != -1; p = edge[p].next)
        {
            if(edge[p].ty == 2)
            {
                if(H[edge[p].v] == -1)
                {
                    s.v = edge[p].v;
                    s.f = f.f + edge[p].w;
                    q.push(s);
                }
            }
        }
    }
}

void bfs(int h,int e,int k)
{
    Q f,s;
    priority_queue<Q> q;
    f.g = 0;
    f.h = H[h];
    f.f = f.h + f.g;
    f.v = h;

    q.push(f);

    while(q.empty() == false)
    {
        f = q.top();
        q.pop();

        if(f.g != 0)
        {
            w[f.v][++ans[f.v]] = f.g;

            if(f.v == e && ans[f.v] == k)
                return ;
        }

        for(int p = head[f.v]; p != -1; p = edge[p].next)
        {
            if(edge[p].ty == 1)
            {
                s.v = edge[p].v;
                s.h = H[edge[p].v];
                s.g = f.g + edge[p].w;
                s.f = s.h + s.g;
                q.push(s);
            }
        }

    }

}

int main()
{

    int n,m;

    int u,v,ww,i;

    while(scanf("%d %d",&n,&m) != EOF)
    {
        memset(head,-1,sizeof(head));

        Top = 0;

        for(i = 0;i < m; ++i)
        {
            scanf("%d %d %d",&u,&v,&ww);
            Link(u,v,ww,1);
            Link(v,u,ww,2);
        }

        int s,t,k;

        scanf("%d %d %d",&s,&t,&k);

        Init_H(t);

        memset(ans,0,sizeof(ans));

        bfs(s,t,k);

        if(ans[t] < k)
        {
            printf("-1\n");
        }
        else
        {
            printf("%d\n",w[t][k]);
        }

    }
    return 0;
}

初涉A*剪枝,布布扣,bubuko.com

时间: 2024-12-20 04:35:33

初涉A*剪枝的相关文章

HDU-4848 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 Olympic Statue) was built.

poj 3134 Power Calculus(迭代加深dfs+强剪枝)

Description Starting with x and repeatedly multiplying by x, we can compute x31 with thirty multiplications: x2 = x × x, x3 = x2 × x, x4 = x3 × x, …, x31 = x30 × x. The operation of squaring can be appreciably shorten the sequence of multiplications.

poj 1198 hdu 1401 搜索+剪枝 Solitaire

写到一半才发现可以用双向搜索4层来写,但已经不愿意改了,干脆暴搜+剪枝水过去算了. 想到一个很水的剪枝,h函数为  当前点到终点4个点的最短距离加起来除以2,因为最多一步走2格,然后在HDU上T了,又发现再搜索过程中,这个估价函数应该是递减的(贪心),再加上这个剪枝就过了. #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<list> #

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

HDU4027 Can you answer these queries 线段树区间求和+剪枝

给了你n,然后n个数字在一个数组中,接下来m个询问,每个询问三个数字 t,x,y,若t==0,那么修改区间[x,y]的每一个值,变为原来每个位置上的数 开根号取整,若t==1,那么对区间[x,y]求和 由于n,m,很大,所以树状数组铁定超时,若直接用线段树来做区间修改,那么也是超时,这类题目没别的方法了,静心剪枝,发现题目给的数据范围为2^63,有没有发现,2^63开根号 绝对不需要开10次,就能到1,到1以后就不需要再开了,意思就是若有某个区间[x,y]每一个点的值都为1时,这一段区间事实上是

Uva140 Bandwidth 全排列+生成测试法+剪枝

参考过仰望高端玩家的小清新的代码... 思路:1.按字典序对输入的字符串抽取字符,id[字母]=编号,id[编号]=字母,形成双射       2.邻接表用两个vector存储,存储相邻关系       3.先尝试字母编号字典序最小的排列,此为next_permutation的最上排列       4.在最理想的情况下都不能得到比当前最优解更好的方案,则应当剪枝(prune)       5.memcpy(),strchr()方法来自于库函数 测试集: Input:      A:FB;B:GC

UVa 208 消防车(dfs+剪枝)

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=144 题意:给出一个n个结点的无向图以及某个结点k,按照字典序从小到大顺序输出从1到结点k的所有路径. 思路:如果直接矩阵深搜的话是会超时的,所以我们可以从终点出发,将与终点相连的连通块保存起来,这样dfs深搜时可以剪枝掉一些到达不了的点.只要解决了这个,dfs就是小问题. 这道题还有点坑的

POJ1190生日蛋糕[DFS 剪枝]

生日蛋糕 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18236   Accepted: 6497 Description 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱.当i < M时,要求Ri > Ri+1且Hi > Hi+1. 由于要在蛋糕上抹奶油,为尽可能

HDU5887 Herbs Gathering(搜索 剪枝)

背包问题,由于数据大不容易dp,改为剪枝,先按性价比排序,若剩下的背包空间都以最高性价比选时不会比已找到的最优解更好时则剪枝,即 if(val + (LD)pk[d].val / (LD)pk[d].w * (lim - w) + EPS <= ans){ return; } 没想到一发过,0ms #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #inclu