HDOJ-2112-HDU Today 解题报告

       最短路问题,只是牵扯到了字符串的操作。题目是中文描述就不多说了。因为这道题不像普通的最短路问题以数字来给地点编号,而是以地点的名称来确定,所以更加结合实际问题,但是又不方便解题。那么应该把地点的名称用数字来编号,把名称转换成编号来解题,这才是关键。


       注意:此题中的路为无向的;如果无法从起点到达终点,输出为-1,这是题目没有说明的;如果起点就是终点,输出为0。此题用C或C++编译器的运行时间比GCC和G++短。


       下面是解题代码:Dijkstra解法

#include <stdio.h>
#include <string.h>
#define N 151
#define NAME 31
#define INF 99999999

int map[N][N];
int dis[N];         //从起点到编号为下标的地点的距离
int flag[N];
char name[N][NAME];
int na;     //站点的个数
int n;      //道路的个数

void Init();    //初始化

void Read();    //输入

int Count(char s[]);    //计算字符串对应的编号

void Dijkstra();

int main()
{
    while (~scanf("%d", &n))
    {
        if (n == -1) break;
        Init();
        Read();
        Dijkstra();
        if (strcmp(name[1], name[0]) == 0)
        {
            printf("0\n");
            continue;
        }
        printf("%d\n", dis[1] == INF ? -1 : dis[1]);
    }
    return 0;
}

void Init()     //初始化
{
    int i, j;
    for (i=0; i<N; ++i)
    {
        for (j=0; j<N; ++j)
        {
            map[i][j] = INF;
        }
        dis[i] = INF;
        flag[i] = 0;
    }
    scanf("%s %s", name[0], name[1]);
    na = 2;
    return;
}

void Read()     //输入
{
    int i;
    char sa[NAME], sb[NAME];
    int a, b, c;
    for (i=0; i<n; ++i)
    {
        scanf("%s %s %d", sa, sb, &c);
        a = Count(sa);
        b = Count(sb);
        map[a][b] = map[b][a] = c;
    }
    return;
}

int Count(char s[])     //计算字符串对应的编号
{
    int i;
    for (i=0; i<na; ++i)
    {
        if (strcmp(name[i], s) == 0)
        {
            return i;
        }
    }
    strcpy(name[na++], s);
    return (na - 1);
}

void Dijkstra()
{
    int i, j, k;
    int min;
    dis[0] = 0;
    for (j=0; j<na; ++j)
    {
        min = INF;
        for (i=0; i<na; ++i)
        {
            if (flag[i] == 0 && min > dis[i])
            {
                min = dis[k = i];
            }
        }
        flag[k] = 1;
        for (i=0; i<na; ++i)
        {
            if (flag[i] == 0 && dis[i] > dis[k] + map[k][i])
            {
                dis[i] = dis[k] + map[k][i];
            }
        }
    }
    return;
}

       接下来是Floyd解法,比Dijkstra解法耗时长,但是优势在于代码编写简单

#include <stdio.h>
#include <string.h>
#define N 151
#define NAME 31
#define INF 9999999

int map[N][N];
char name[N][NAME];
int na;     //站点的个数
int n;      //道路的个数

void Init();    //初始化

void Read();    //输入

int Count(char s[]);    //计算字符串对应的编号

void Floyd();

int main()
{
    while (~scanf("%d", &n))
    {
        if (n == -1) break;
        Init();
        Read();
        Floyd();
        if (strcmp(name[1], name[0]) == 0)
        {
            printf("0\n");
            continue;
        }
        printf("%d\n", map[0][1] == INF ? -1 : map[0][1]);
    }
    return 0;
}

void Init()     //初始化
{
    int i, j;
    for (i=0; i<N; ++i)
    {
        for (j=0; j<N; ++j)
        {
            map[i][j] = INF;
        }
    }
    scanf("%s %s", name[0], name[1]);
    na = 2;
    return;
}

void Read()     //输入
{
    int i;
    char sa[NAME], sb[NAME];
    int a, b, c;
    for (i=0; i<n; ++i)
    {
        scanf("%s %s %d", sa, sb, &c);
        a = Count(sa);
        b = Count(sb);
        map[a][b] = map[b][a] = c;
    }
    return;
}

int Count(char s[])     //计算字符串对应的编号
{
    int i;
    for (i=0; i<na; ++i)
    {
        if (strcmp(name[i], s) == 0)
        {
            return i;
        }
    }
    strcpy(name[na++], s);
    return (na - 1);
}

void Floyd()
{
    int i, j, k;
    for (k=0; k<na; ++k)
    {
        for (i=0; i<na; ++i)
        {
            for (j=0; j<na; ++j)
            {
                if (map[i][j] > map[i][k] + map[k][j])
                {
                    map[i][j] = map[i][k] + map[k][j];
                }
            }
        }
    }
    return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值