HDU3499Flight(双向Dijkstra)

来源:互联网 发布:python 面部表情识别 编辑:程序博客网 时间:2024/06/05 15:45

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

题意:

        有一个有向图,你要从特定的城市A飞到城市B去.给你这个图的所有边(航班)信息.但是你手上有一张卡,可以使得某一趟航班的价格减半.现在的问题是你从A到B的最小费用是多少?

分析:

        首先要知道这条如果让一条原本是最短路径(假设总距离为x)上最长的边变成半价,最终求得的解不一定是最优的。因为假如现在有另外一条路径,假设该路径距离为x+1。且这条路径上只有5条边,4条长为1的边,但是1条长为x-3的边。如果我们让这条路径的x-3边变成半价是不是能得到更好的结果?

        明显必须从m条边中枚举那条半价的航班.假设这条半价的航班是i->j的.那么我们必须知道从A到i的最短距离和从j到B的最短距离. 从A到i的最短距离可以通过求A的单源最短路径即可.从j(j有可能是任意点)到B的最短距离必须建立原图的反向图,然后求B到其他所有点的单源最短路径.(想想是不是)

        原题输入数据很多,需要用邻接表的dijkstra算法且距离要用long long保存


结构体封装代码:

#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#include<queue>#include<map>using namespace std;const long long INF = 1e17;const int maxn = 100005;const int maxm = 500005;int n, m;map<string, int> mp;struct Edge{    int form, to, next;    long long dist;    Edge(){}    Edge(int _form, int _to, long long _dist):form(_form), to(_to), dist(_dist){}    Edge(int _form, int _to, long long _dist, int _next):form(_form), to(_to), dist(_dist), next(_next){}}edge[maxm];struct HeapNode{    long long d;    int u;    HeapNode(){}    HeapNode(int _u, long long _d):u(_u), d(_d){};    bool operator < (const HeapNode &other) const    {        return d > other.d;    }};struct Dijkstra{    int n, m, head[maxm];    Edge edge[maxm];    long long dis[maxn];    void init()    {        m = 0;        memset(head, -1, sizeof(head));    }    void add_edge(int from, int to, long long dist)    {        edge[m] = Edge(from, to, dist, head[from]);        head[from] = m++;    }    void dijkstra(int s)    {        priority_queue<HeapNode> q;        for(int i = 0; i < n; i++)            dis[i] = i == s ? 0 : INF;        q.push(HeapNode(s, dis[s]));        while(!q.empty())        {            HeapNode x = q.top();            q.pop();            int u = x.u;            for(int i = head[u]; i != -1; i = edge[i].next)            {                if(dis[edge[i].to] > dis[u] + edge[i].dist)                {                    dis[edge[i].to] = dis[u] + edge[i].dist;                    q.push(HeapNode(edge[i].to, dis[edge[i].to]));                }            }        }    }}dj1, dj2;int getid(string s){    if(mp.find(s) == mp.end())        mp[s] = n++;    return mp[s];}int main(){    int u, v;    long long w;    while(scanf("%d%d", &n, &m) != EOF)    {        n = 0;        mp.clear();        string s1, s2;        dj1.init();dj2.init();        for(int i = 0; i < m ; i++)        {            cin >> s1 >> s2 >> w;            u = getid(s1);            v = getid(s2);            dj1.add_edge(u, v, w);            dj2.add_edge(v, u, w);            edge[i] = Edge(u, v, w);        }        cin >> s1 >> s2;        int st = getid(s1), ed = getid(s2);        dj1.n = dj2.n = n;        dj1.dijkstra(st), dj2.dijkstra(ed);        if(dj1.dis[ed] == INF)        {            printf("-1\n");            continue;        }        long long ans = INF;        for(int i = 0; i < m; i++)        {            int u  = edge[i].form, v = edge[i].to;            long long w  = edge[i].dist;            if(ans >  dj1.dis[u] + dj2.dis[v] + w / 2)                ans =  dj1.dis[u] + dj2.dis[v] + w / 2;        }        printf("%I64d\n", ans);    }    return 0;}

二维数组代码:

#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#include<queue>#include<map>using namespace std;const int maxm = 500005;const int maxn = 100005;const long long INF = 1e17;struct Edge{    int u, v, next;    long long w;    Edge(){}    Edge(int _u, int _v, long long _w, int _next):u(_u), v(_v), w(_w), next(_next){}}edge[2][maxm];struct HeapNode{    long long d;    int u;    HeapNode(int _u, long long _d):u(_u), d(_d){}    bool operator < (const HeapNode &other)const    {        return d > other.d;    }};int n, m, head[2][maxn];long long dis[2][maxn];map<string, int> mp;int getid(string s){    if(mp.find(s) == mp.end())        mp[s] = n++;    return mp[s];}void Dijkstra(int flag, int s){    for(int i = 0; i < n; i++)        dis[flag][i] = INF;    dis[flag][s] = 0;    priority_queue<HeapNode> q;    q.push(HeapNode(s, dis[flag][s]));    while(!q.empty())    {        HeapNode now = q.top();        q.pop();        for(int i = head[flag][now.u]; i != -1; i = edge[flag][i].next)        {            int to = edge[flag][i].v;            if(dis[flag][to] > dis[flag][now.u] + edge[flag][i].w)            {                dis[flag][to] = dis[flag][now.u] + edge[flag][i].w;                q.push(HeapNode(to, dis[flag][to]));            }        }    }}int main(){    while(scanf("%d%d", &n, &m) != EOF)    {        n = 0;        string s1, s2;        mp.clear();        memset(head, -1, sizeof(head));        memset(dis, 63, sizeof(dis));        for(int i = 0; i < m; i++)        {            long long w;            cin >> s1 >> s2 >> w;            int u = getid(s1), v = getid(s2);            edge[0][i] = Edge(u, v, w, head[0][u]);            head[0][u] = i;            edge[1][i] = Edge(v, u, w, head[1][v]);            head[1][v] = i;        }        cin >> s1 >> s2;        int st = getid(s1), ed = getid(s2);        Dijkstra(0, st);        Dijkstra(1, ed);        if(dis[0][ed] == INF)        {            printf("-1\n");            continue;        }        long long ans = INF;        for(int i = 0; i < m; i++)        {            int u = edge[0][i].u, v = edge[0][i].v;            long long dist = edge[0][i].w;            if(ans > dis[0][u] + dis[1][v] + dist / 2)                ans = dis[0][u] + dis[1][v] + dist / 2;        }        printf("%I64d\n", ans);    }    return 0;}



0 0
原创粉丝点击