★☆【启发式搜索】【图论】Remmarguts' Date

来源:互联网 发布:it是什么 编辑:程序博客网 时间:2024/09/21 06:21
Description"Good man never makes girls wait or breaks an appointment!" said the mandarin duck father.Softly touching his little ducks' head, he told them a story."Prince Remmarguts lives in his kingdom UDF – United Delta of Freedom. One day their neighboringcountry sent them Princess Uyuw on a diplomatic mission.""Erenow, the princess sent Remmarguts a letter, informing him that she would come to the halland hold commercial talks with UDF if and only if the prince go and meet her via the K-thshortest path. (in fact, Uyuw does not want to come at all)"Being interested in the trade development and such a lovely girl, Prince Remmarguts reallybecame enamored. He needs you - the prime minister's help!DETAILS: UDF's capital consists of N stations. The hall is numbered S, while the stationnumbered T denotes prince' current place. M muddy directed sideways connect some of thestations. Remmarguts' path to welcome the princess might include the same station twiceor more than twice, even it is the station with number S or T. Different paths with samelength will be considered disparate.InputThe first line contains two integer numbers N and M (1 <= N <= 1000, 0 <= M <= 100000).Stations are numbered from 1 to N. Each of the following M lines contains three integernumbers A, B and T (1 <= A, B <= N, 1 <= T <= 100). It shows that there is a directedsideway from A-th station to B-th station with time T.The last line consists of three integer numbers S, T and K (1 <= S, T <= N, 1 <= K <= 1000).OutputA single line consisting of a single integer number: the length (time required) to welcomePrincess Uyuw using the K-th shortest path. If K-th shortest path does not exist, you shouldoutput "-1" (without quotes) instead.Sample Input2 21 2 52 1 41 2 2Sample Output14

题目很简单,首先用一个Dijkstra将所有点到终点的距离算出来,然后用A*启发式搜索搜出K次到终点的路径即为第K短路。
全局变量是个很危险的东西啊,以后再也不用了……
Accode:

#include <cstdio>#include <string>#include <cstdlib>#include <algorithm>#include <queue>using namespace std;const char fi[] = "poj2449.in";const char fo[] = "poj2449.out";const int maxN = 1010;const int MAX = 0x3f3f3f3f;const int MIN = ~MAX;int h[maxN];struct Node{    int v, g;    Node (int v, int g): v(v), g(g) {}    inline bool operator<(const Node &b) const    {        return h[v] + g > h[b.v] + b.g;//今天把右边的"b.g"打成了"g",然后……    }};struct Edge{    int v, d;    Edge *next;};Edge *edge[maxN];Edge *redge[maxN];int cnt[maxN];priority_queue <Node> hp;int n, m, K, S, T;void init_file(){    freopen(fi, "r", stdin);    freopen(fo, "w", stdout);    return;}inline int getint(){    int res = 0;    char tmp;    while (!isdigit(tmp = getchar()));    do res = (res << 3) + (res << 1) + tmp - '0';    while (isdigit(tmp = getchar()));    return res;}inline void insert(int u, int v, int d){    Edge *p = new Edge;    p -> v = v;    p -> d = d;    p -> next = edge[u];    edge[u] = p;    p = new Edge;    p -> v = u;    p -> d = d;    p -> next = redge[v];    redge[v] = p;}void readdata(){    n = getint();    m = getint();    for (; m; --m)    {        int u, v, d;        u = getint();        v = getint();        d = getint();        insert(u, v, d);    }    S = getint();    T = getint();    K = getint();    if (S == T) ++K;//若起点和终点相等,即变为找第(K + 1)短路。    return;}void Dijkstra(){    while (!hp.empty()) hp.pop();    memset(cnt, 0, sizeof cnt);    memset(h, 0x3f, sizeof h);    h[T] = 0;    hp.push(Node(T, h[T]));    while (!hp.empty())    {        int u = hp.top().v;        hp.pop();        if (cnt[u]) continue;        ++cnt[u];        for (Edge *p = redge[u]; p; p = p -> next)        if (!cnt[p -> v] && h[u] + p -> d < h[p -> v])//一不小心把v定义成全局变量,然后把cnt[p -> v]//中的p -> v打成了v,结果……        {            h[p -> v] = h[u] + p -> d;            hp.push(Node(p -> v, h[p -> v]));        }    }    return;}int Search(){    if (h[S] == MAX) return -1;    hp = priority_queue <Node>();    memset(cnt, 0, sizeof cnt);    hp.push(Node(S, 0));    while (!hp.empty())    {        int u = hp.top().v, g = hp.top().g;        hp.pop();        ++cnt[u];        if (cnt[T] == K) return g;        if (cnt[u] > K) continue;        for (Edge *p = edge[u]; p; p = p -> next)            hp.push(Node(p -> v, g + p -> d));    }    return -1;}int main(){    init_file();    readdata();    Dijkstra();    printf("%d\n", Search());    return 0;}
第二次做:

#include <cstdio>#include <cstdlib>#include <algorithm>#include <string>const int maxN = 1010;int h[maxN];struct Node{    int v, g;    Node() {}    Node(int v, int g): v(v), g(g) {}    bool operator<(const Node &b)    {return g + h[v] > b.g + h[b.v];}};struct Edge {int v, d; Edge *next;};Edge *edge[maxN], *redge[maxN];Node hp[maxN << 10];int cnt[maxN], n, m, S, T, K, top;inline void ad_down(){    for (int i = 1; (i <<= 1) <= top;)    {        if (i < top && hp[i] < hp[i + 1]) ++i;        if (hp[i >> 1] < hp[i])            std::swap(hp[i], hp[i >> 1]);        else break;    }    return;}inline void ad_up(){    for (int i = top; i >> 1; i >>= 1)    {        if (hp[i >> 1] < hp[i])            std::swap(hp[i], hp[i >> 1]);        else break;    }    return;}inline void Dijkstra(){    memset(h, 0x3f, sizeof h);    for (hp[top = 1] = Node(T, h[T] = 0); top;)    {        int u = hp[1].v; hp[1] = hp[top--]; ad_down();        if (cnt[u]) continue; cnt[u] = 1;        for (Edge *p = redge[u]; p; p = p -> next)        if (!cnt[p -> v] && h[u] + p -> d < h[p -> v])        {            int v = p -> v; h[v] = h[u] + p -> d;            hp[++top] = Node(v, h[v]); ad_up(); //        }    }    return;}inline int Search(){    if (h[S] == 0x3f3f3f3f) return -1; //    memset(cnt, 0, sizeof cnt);//    if (S == T) --cnt[S];    for (hp[top = 1] = Node(S, 0); top;)    {        int u = hp[1].v, d = hp[1].g;        hp[1] = hp[top--]; ad_down();        ++cnt[u];        if (cnt[T] >= K) return d;        if (cnt[u] > K) continue;        for (Edge *p = edge[u]; p; p = p -> next)        {hp[++top] = Node(p -> v, d + p -> d); ad_up();}    }    return -1;}inline int getint(){    int res = 0; char tmp;    while (!isdigit(tmp = getchar()));    do res = (res << 3) + (res << 1) + tmp - '0';    while (isdigit(tmp = getchar()));    return res;}inline void Ins(int u, int v, int d){    Edge *p = new Edge; p -> v = v; p -> d = d;    p -> next = edge[u]; edge[u] = p;    p = new Edge; p -> v = u; p -> d = d;    p -> next = redge[v]; redge[v] = p;    return;}int main(){    freopen("Remmarguts'_Date.in", "r", stdin);    freopen("Remmarguts'_Date.out", "w", stdout);    n = getint(); m = getint();    for (; m; --m)    {        int u = getint(),        v = getint(), d = getint();        Ins(u, v, d);    }    S = getint(); T = getint(); K = getint();    if (S == T) ++K;    Dijkstra();    printf("%d\n", Search());    return 0;}