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

这一题与上面的图论的题有很大不同,对于这一题对于这题有两种解法,Dijkstra算法或者floyd算法,只是我也没理解好,在别人的帮助下勉强整出dijkstra算法解这一题,

由于题目本身比上几个稍微难理解点,所以附上dijkstra算法的课件的部分; 

Dijkstra算法

依最短路径的长度递增的次序求得各条路径。

设置一个集合S,该集合中存放从给定源点出发最短路径已知的所有顶点。

因此算法开始时,集合S中只有源点一个顶点。随着算法的进行,其余的顶点被逐步加入集合S。因此算法要解决的问题是确定每步应该加入哪个顶点?

设定一个数组int distance[graph_size];记录从源点到其它顶点的距离

若顶点v已在S中,则distance[v]记录了从源点到顶点v的最短距离。

若顶点v还未加入S中,则distance[v]记录了从源点到某个S中的顶点w的最短距离加上边<w,v>的权值。

distance数组的初始化。 (1)若从源点邻接到顶点v(有边的情况),则distance[v]即为该边的权值。(2)否则(无边的情况),则distance[v]为无穷大。

算法进行时,从distance中找一个最小值,并将其对应的顶点加入到S中。

一旦某顶点v加入S,则重新计算尚未加入S的顶点所对应的数组distance元素值。更新规则为:

若distance[w] > distance[v]+weight(<v,w>),

令 distance[w] = distance[v]+weight(<v,w>)

如此循环往复,直到把所有顶点加入S。

View Code
# include<stdio.h>
# include<string.h>
int map[160][160];
int flag[160];
int count[160];
char str[160][40];
int k;
int dijkstra(int kk)//dijkstra算法
{
    int i,j,t,min;
    for(i=0;i<k;i++)
    {
        flag[i]=0;
        count[i]=map[kk][i];
    }
    flag[kk]=1;
    count[kk]=0;
    for(i=0;i<k;i++)
    {
        min=1000000000;
        for(j=1;j<k;j++)//经过k次遍历,是足以遍历完的
        {
            if(flag[j]==0&&count[j]<min)
            {
                min=count[j];
                t=j;
            }
        }
        if(min==1000000000)
            break;
        flag[t]=1;//标记
        for(j=0;j<k;j++)////更新
        {
            if(flag[j]==0&&count[j]>count[t]+map[t][j])
                count[j]=count[t]+map[t][j];
        }
    }
    return count[1];
}
int main()
{
    int i,j,k1,k2,n,d;
    char str1[11000][40],str2[11000][40];
    while(scanf("%d",&n),n!=-1)
    {
        for(i=0;i<155;i++)
            for(j=0;j<155;j++)
                map[i][j]=1000000000;
        scanf("%s%s",str1[0],str2[0]);
        strcpy(str[0],str1[0]);
        strcpy(str[1],str2[0]);
        k=2;
        for(i=1;i<=n;i++)//这种处理还是好理解的
        {
            scanf("%s%s%d",str1[i],str2[i],&d);
            for(j=0;j<k;j++)
            {
                if(strcmp(str[j],str1[i])==0)
                {
                    k1=j;
                    break;
                }
            }
            if(j==k)
            {
                k1=j;
                strcpy(str[k],str1[i]);
                k++;
            }
            for(j=0;j<k;j++)
            {
                if(strcmp(str[j],str2[i])==0)
                {
                    k2=j;
                    break;
                }
            }
            if(j==k)
            {
                k2=j;
                strcpy(str[k],str2[i]);
                k++;
            }
            if(map[k1][k2]>d)
                map[k1][k2]=d;
            if(map[k2][k1]>d)
                map[k2][k1]=d;            
        }
        if(strcmp(str1[0],str2[0])==0)//判断始点是否为终点
        {
            printf("0\n");
            continue;
        }
        else
        {
            d=dijkstra(0);
            if(d==1000000000)
                printf("-1\n");
            else
                printf("%d\n",d);
        }    
    }
    return 0;
}

 

  
posted on 2011-08-09 20:01  world_ding  阅读(266)  评论(0编辑  收藏  举报