hdu3790 最短路径问题(Dijkstra)

本文出自:http://blog.csdn.net/svitter

原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=3790

另外写文章之前偷懒一下,发现一个很好的入门python教程!:http://woodpecker.org.cn/abyteofpython_cn/chinese/

题意:在最短路径的前提下,添加了一个最短路径中权值最小的要求。

使用dijkstra算法。

注意此图是无向图,输入时保存最优的路径和权值。

具体细节在代码中:

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;
#define INF 0x1f1f1f1f //防止不用fffffff防止溢出
#define min(a, b) a < b? a : b
struct Cost
{
    int l;
    int c;
};

struct Low
{
    int l;
    int c;
};

Cost cost[1001][1001];
Low low[1001];
bool flag[1001];
int s; //出发点

void Dijkstra(int n)
{
    int i, j, k;
    memset(flag, 0, sizeof(flag));
    memset(low, 0x1f, sizeof(low));
    flag[s] = 1;
    for(i = 1; i <= n; i++)
    {
        low[i].l = cost[s][i].l; //s到任意点的距离
        low[i].c = cost[s][i].c; //s到任意点的花费
    }
    low[s].l = 0;
    low[s].c = 0;

    for(i = 2; i < n; i ++)
    {
        int min = INF;
        int val = INF;
        for(j = 1; j <= n; j++)
        {
            if(flag[j] == 0 && low[j].l <= min)//到当前点距离
            {
                if(low[j].l == min)
                {
                    if(low[j].c < val)
                    {
                        val = low[j].c;
                        k = j;
                    }
                    else //在length和value都相等的前提下,添加任何一个点都是一样的
                        continue;
                }
                else
                {
                    min = low[j].l;
                    val = low[j].c;
                    k = j;
                }
            }
        }
        flag[k] = 1;
        for(j = 1; j <= n; j++)
        {
            if(flag[j] == 0 && cost[k][j].l + low[k].l <= low[j].l)//依据这个点修改最短路径
            {
                if(cost[k][j].l + low[k].l < low[j].l)
                {
                    low[j].l = low[k].l + cost[k][j].l;
                    low[j].c = low[k].c + cost[k][j].c;
                }
                else
                {
                    low[j].c = min(low[j].c, cost[k][j].c + low[k].c);
                }
            }
        }
    }
}
void ace()
{
    int i, t;//work point
    int m, n;
    int a, b, d, p;
    while(scanf("%d%d", &n, &m))
    {
        if(m == 0 && n == 0)
            break;
        memset(cost, INF, sizeof(cost));
        for(i = 0; i < m; i++)
        {
            scanf("%d%d%d%d", &a,&b,&d,&p);
            if(cost[a][b].l > d)
            {
                cost[a][b].l = cost[b][a].l = d;
                cost[a][b].c = cost[b][a].c = p;
            }
            else if(cost[a][b].l == d && cost[a][b].c < p)
            {
                cost[a][b].c = cost[b][a].c = p;
            }
            else
                continue;
        }
        scanf("%d%d", &s, &t);

        Dijkstra(n);

        printf("%d %d\n", low[t].l, low[t].c);

    }
}

int main()
{
    ace();
    return 0;
}


你可能感兴趣的:(C++,编程语言,ACM,图论,kruskal)