poj 1603 Risk(最短路)


一看题目给的图,再看看数据,大致就知道是最短路的题目了。
题目本身不难,关键是在于理解数据的含义。
每组数据先输入19组边信息,依次代表从第几个顶点出发有哪些边与之直接相连。
要注意的是图是无向图,所以在更改邻接矩阵时根据无向图的对称性来处理数据

要注意到题目要求的格式控制,是整个输入连通性的信息加上查找的输入算做一组数据,而不是只是查找最短路径时的输入为一组数据。悲剧的在这里WR一次。。。

这个题按理来说用弗洛伊德算法就完事了。。我在这里用的是迪杰斯特拉算法。。。其实时间复杂度是差不多的。弗洛伊德不就是n个迪杰斯特拉嘛?

要注意的是,迪杰斯特拉是来依次求出小的权值,所以邻接矩阵在初始化是全部为无穷大!。。。一开始没有注意全部是0结果肯定是悲剧了。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXNODE 25
#define MAXCOST 9999
using namespace std;
int main()
{
    void InputCost(int Cost[][MAXNODE]);
    void Dijkstra(int Cost[][MAXNODE],int f,int Distance[],int e);
    int Cost[MAXNODE][MAXNODE];
    int cnt;
    int kkk = 0; /*kkk为格式控制中的数据编号*/
    int n,k;
    int i,f,e,Distance[MAXNODE];
    while(cin>>n) /*格式控制*/ /*题目已说明总共19组数据,先在input函数外输入一组用于方便格式控制*/
   {
        memset(Cost,0x3f,sizeof(Cost));
        while(n--)
        {
            cin>>k;
            Cost[1][k] = 1;
            Cost[k][1] = 1;
        }
        InputCost(Cost);
        cin>>cnt; /*输入查找的信息 */
        ++kkk;
        printf("Test Set #%d\n",kkk);
        while(cnt--)
        {
            cin>>f>>e;
            Dijkstra(Cost,f,Distance,e);
        }
        putchar(10);
   }
    return 0;
}
void InputCost(int Cost[][MAXNODE]) /*数据输入,用邻接矩阵来存储图的信息*/
{
    int n,k;

    for(int i = 2 ; i <= 19 ; i++)
    {
        scanf("%d",&n);
        for(int j = 0 ; j < n ; j++)
        {
            scanf("%d",&k);
            Cost[i][k] = 1;
            Cost[k][i] = 1;
        }
    }
}
void Dijkstra(int Cost[][MAXNODE],int f,int Distance[],int e)/*f为出发的结点,e为要查找的从f出发到e的顶点*/
{
    int s[MAXNODE];
    int mindis,dis;
    int i,j,u;
    for(i=1;i<=20;i++)   /*对S数组初始化*/
    {
        Distance[i]=Cost[f][i];
        s[i]=0;
    }
    s[f]=1;   /*标记v0.*/
    for(i=1;i<=20;i++)
    {
        mindis=MAXCOST;
        for(j=1;j<=20;j++)
        {
            if(s[j]==0 && Distance[j]<mindis)  /*每一次循环比较得到最短值。*/
            {
                u=j;
                mindis=Distance[j];
            }
        }
        s[u]=1;   /*标记u.*/
        for(j=1;j<=20;j++)
        {
            if(s[j]==0)
            {
                dis=Distance[u]+Cost[u][j];
                Distance[j]=(Distance[j]<dis)?Distance[j]: dis;   /*修改从初始结点到其他顶点的最短距离。*/
            }
        }
    }
    printf("%d to %d: %d\n",f,e,Distance[e]);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值