杭电 3790 最短路径问题

题目地址:

http://acm.hdu.edu.cn/showproblem.php?pid=3790

    没什么太大的感觉,只是觉得进步是一个过于缓慢的感觉……

  dijkstra算法的应用,注意可重边的处理以及同等权值的路径时,路径的选择

#include <stdio.h>
#define MAXN 1010
#define INF 1000000000

int mat[MAXN][MAXN];
int bb[MAXN][MAXN];
int min[MAXN];
int pre[MAXN];

int com(int m, int s, int a, int b)
{
    int path1[MAXN], path2[MAXN], i = 2, j = 2;
    int sum1 = 0, sum2 =0, p;
    path1[0] = path2[0] = m;
    path1[1] = a;
    path2[1] = b;

    while( a != s )
    {
        path1[i++] = pre[a];
        a = pre[a];
    }
    while( b != s )
    {
        path2[j++] = pre[b];
        b = pre[b];
    }
    for( p = 0; p < (i-1); p++ )
        sum1 += bb[path1[p]][path1[p+1]];
    for( p = 0; p < (j-1); p++ )
        sum2 += bb[path2[p]][path2[p+1]];
    if( sum1 >= sum2 )
        return path2[1];
    return path1[1];
}
void Dijkstra(int n,int s)
{
    int v[MAXN], i, j, k;
    for( i = 1; i <=  n; i++  )
        v[i] = 0, min[i] = INF, pre[i] = -1;
    for( min[s] = 0, j = 1; j <= n; j++ )
    {
        for( k = 0, i = 1; i <= n; i++ )
            if( (!v[i]) && ((k == 0)||(min[i] < min[k])) )
                k = i;
        for( v[k] = 1, i = 1; i <= n; i++ )
            if( (!v[i]) && (mat[k][i] != INF) && (mat[k][i] + min[k] < min[i]) )
            {
                min[i] = min[k] + mat[k][i];
                pre[i] = k;
            }
            else if(  !v[i] && (mat[k][i] != INF) && (mat[k][i] + min[k] == min[i]) )
                pre[i] = com(i,s,pre[i],k);
    }
}

int main()
{
    int n, m, k, s, t, sum, end;
    int i, j, a, b;
    while( (scanf( "%d%d", &n, &m)!= EOF) && n && m )
    {
        for( i = 1; i <= n; i++ )
            for( j = 1; j <= n; j++ )
            {
                mat[i][j] = INF;
                bb[i][j] = INF;
            }
        for( k = 0; k < m; k++ )
        {
            scanf("%d%d%d%d", &i, &j, &a, &b);
            if( a < mat[i][j] )
            {
                mat[j][i] = mat[i][j] = a;
                bb[j][i] = bb[i][j] = b;
            }
            else if( (a == mat[i][j])&&(b < bb[i][j]) )
                bb[i][j] = bb[j][i] = b;
        }
        /*for( i = 1; i <= n; i++ )
        {
            for( j = 1; j <= n; j++ )
                printf( "%d ", mat[i][j] );
            printf( "\n" );
        }*/
        scanf("%d%d", &s, &t);
        //printf("%d %d\n",s,t);
        Dijkstra(n,s);
        /*for( i = 1; i <= n; i++ )
            printf( "%d ", min[i] );
        printf( "\n" );
        for( i = 1; i <= n; i++ )
            printf( "%d ", pre[i] );
        printf( "\n" );*/
        //printf("123");
        sum = 0;
        end = t;
        while( end != s )
        {
            sum += bb[end][pre[end]];
            end = pre[end];
        }
        //printf("123");
        printf("%d %d\n",min[t],sum);
    }
    return 0;
}
View Code

 

posted @ 2013-07-29 07:14  翼展zjz  阅读(140)  评论(0编辑  收藏  举报