河南省第七届大学生程序设计竞赛 问题 B: 海岛争霸

题目描述

神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等。加勒比海盗,你知道吧?杰克船长驾驶着自己的的战船黑珍珠1号要征服各个海岛的海盜,最后成为海盗王。  这是一个由海洋、岛屿和海盗组成的危险世界。杰克船长准备从自己所占领的岛屿A开始征程,逐个去占领每一个岛屿。面对危险重重的海洋与诡谲的对手,如何凭借智慧与运气,建立起一个强大的海盗帝国。

杰克船长手头有一张整个海域的海图,上面详细地记录了各个海屿的位置,以及海屿之间的通航路线。但他发现,有的航海路线太危险了,杰克船长的战船很难直接通过,他必须想方设法绕道航行;还有的岛屿根本到达不了。

杰克船长现在想把航行的危险程度降到最小。具体地来说,就是杰克船长提出若干个询问,他想知道从岛屿A 到岛屿B 有没有行驶航线,若有的话,所经过的各个航线中,最小的危险程度航线是哪条,至少危险程度是多少。

输入

第1行:     N  M        表示有N个岛屿,M条直航路线

第2~M+1行:     A   B   V  表示从岛屿A到岛屿B的航线上的危险程度值为V。

接下面一行 :   Q          表示询问的次数。

之后有Q个行:   A  B       询问从岛屿A 到岛屿B 所经过的航线,至少的危险程度是多少

输出

对于每个询问,输出占一行,一个整数,表示从岛屿A 到岛屿B 所经过的航线,至少的危险程度值;若从岛屿A 无法到达岛屿B,则输出-1。

样例输入

10 8
1 2 5
1 3 3
2 3 7
2 4 6
3 4 4
6 7 10
6 10 5
10 7 2
5
2 3
1 4
3 7
6 7
8 3

样例输出

5
4
-1
5
-1

提示


 1<N≤200  0<M≤500   1≤ Q≤20   0 < V ≤1000

题意:我们需要找到每条从起始岛屿到终止岛屿的最大危险程度值,然后从这些最大危险程度值中比较出最小的,就是题目要求的“至少危险程度值”。

思路:dijstra的变形题,dis数组在此时的作用就是存已经查找过的航线的"至少危险程度值",如果之后出现的航线中有比这个值更大的,都更新为当前这个航线的值。

错误总结:1:结构体数组不能直接用结构体类型去定义,否则会显示编译错误(其实这本来就是不规范的定义方式)

2:仔细审题,题目要求一边询问一边输出,而不是全部询问完再输出值。

#include<stdio.h>
#include<string.h>
#define N 2100
#define inf 0x3f3f3f3f
int book[N],map[N][N],dis[N];
int n,m,e,s,ans;
void dijstra()
{
    int i,j,u,min,t;
    memset(book,0,sizeof(book));
    for(i = 1; i <= n; i ++)
        dis[i] = map[s][i];//需要的是起始岛屿s到各个岛屿的值 
    book[s] = 1;    //标记起始岛屿为已经走过
    u = 0; 
    for(i = 1; i <= n; i ++)
    {
        min = inf;
        for(j = 1; j <= n; j ++)
        {
            if(!book[j]&&dis[j] < min)
            {
                min = dis[j];
                u = j;
            }
        }
        if(u == 0)//当前询问不符合条件,直接退出 
            return;
        book[u] = 1;
        for(j = 1; j <= n; j ++)
        {
            if(dis[u] > map[u][j])
                t = dis[u];
            else
                t = map[u][j];
            if(!book[j]&&dis[j] > t)
                dis[j] = t;
        }
    }
    ans = dis[e];
    return;
}
int main()
{
    int i,j,t1,t2,t3,x,y;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i = 1; i <= n; i ++)
            for(j = 1; j <= n; j ++)
                if(i == j)
                    map[i][j] = 0;
                else
                    map[i][j] = inf;//初始化地图 
        for(i = 1; i <= m; i ++)
        {
            scanf("%d%d%d",&t1,&t2,&t3);//读入直航路线和危险程度值 
            map[t1][t2] = t3;
            map[t2][t1] = t3;
        }
        scanf("%d",&t1);//读入询问次数 
        for(i = 1; i <= t1; i ++)
        {
            scanf("%d%d",&x,&y);//读入询问的边 
            s = x ;//起始岛屿 
            e = y ;//终止岛屿 
            ans = inf;
            dijstra();//找到最小危险程度值 
            if(ans == inf)//如果没有直航路线 
                printf("-1
");
            else
                printf("%d
",ans);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hellocheng/p/7412277.html