1003. Emergency (25)

下午时候还说要做8题呢。。。。到现在才完成3题。。。还是要看书和看网上答案

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.

Input

Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (<= 500) - the number of cities (and the cities are numbered from 0 to N-1), M - the number of roads, C1 and C2 - the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2 and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C2.

Output

For each test case, print in one line two numbers: the number of different shortest paths between C1 and C2, and the maximum amount of rescue teams you can possibly gather.
All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.

Sample Input
5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1
Sample Output
2 4

题目其实不难。。。。只是我没见过大蛇屙屎。。。一直用结构体来做图。。。。现在才认识到图只是一个概念。。。不一定用结构体来实现,考试时候用结构体,把函数写完,估计就gg了。


这题参考网上用了两种方法来做,分别是dijkstra和DFS


dijkstra

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define INF 0x3f3f3f
#define MAXSIZE 501

int map[MAXSIZE][MAXSIZE];
int pathCnt[MAXSIZE]; /**< 计算到某城市最短路径一共有多少条 */
int dist[MAXSIZE];
int collect[MAXSIZE] = {0};
int teams[MAXSIZE];
int totalTeam[MAXSIZE];

int numOfCity, numOfRoad, sCity, eCity;

void dijkstra(int start);
void dijkstra(int start)
{
    totalTeam[start] = teams[start];
    dist[start] = 0;    /**< 起点距离设置为0 */
    pathCnt[start] = 1;  /**< 到start的起点只有一条 */

    while(1)
    {
        int i, minIndex;
        int minDist = INF;
        for(i=0; i<numOfCity; i++)
        {
            if(collect[i]==0 && dist[i]<minDist)
            {
                minIndex = i;
                minDist = dist[i];
            }
        }

        if(minDist==INF || minIndex==eCity)  /**< minDist==INF表示所有顶点已经收录,minDist==eCity表示已经收录到目标城市了,满足两者其中一个条件就可以结束搜索  */
            break;

        collect[minIndex] = 1;


        for(i=0; i<numOfCity; i++)
        {
            if(collect[i]==0 && map[minIndex][i]<INF )
            {
                if(dist[minIndex] + map[minIndex][i] < dist[i]) /**< 新的距离小于现有距离,更新dist表中距离 */
                {
                    dist[i] = dist[minIndex] + map[minIndex][i];
                    totalTeam[i] = totalTeam[minIndex] + teams[i];
                    pathCnt[i] = pathCnt[minIndex];  /**< 到上一个城市有多少条最短路径,那么由这个城市出发到下一个城市的最短路径也有多少条 */
                }
                else if(dist[minIndex] + map[minIndex][i] == dist[i])
                {
                    pathCnt[i] += pathCnt[minIndex];   /**< 出现相等情况,1、证明i点已出现过一次最短路径,2、上一个有几条最短路径应该加到原来dist[i]里 */

                    if(totalTeam[i] < totalTeam[minIndex]+teams[i])
                    {
                        totalTeam[i] = totalTeam[minIndex]+teams[i];
                    }
                }

            }
        }
    }
}

int main()
{
    int i, j;
    scanf("%d %d %d %d", &numOfCity, &numOfRoad, &sCity, &eCity);  //一开始这里最后一个&eCity写错了,写成&sCity是,喵的,这样居然前3三个用例能ac,导致我一直找不到哪里有问题

    for(i=0; i<numOfCity; i++)
    {
        scanf("%d", &teams[i]);
    }

    for(i=0; i<numOfCity; i++)
    {
        dist[i] = INF; /**< 所有顶点距离初始化无穷大 */
        for(j=0; j<numOfCity; j++)
        {
            map[i][j] = INF; /**< 邻接矩阵初始化为无穷大,即,城市间都不连通 */
        }
    }

    for(i=0; i<numOfRoad; i++)
    {
        int x, y, z;
        scanf("%d %d %d", &x, &y, &z);
        map[x][y] = map[y][x] = z; /**< 注意是双向图,需要双向赋值 */
    }
    dijkstra(sCity);
    printf("%d %d", pathCnt[eCity], totalTeam[eCity]);
    system("pause");
}

DFS

#include <stdio.h>
#include <stdlib.h>

#define INF 0x3f3f3f
#define MAXSIZE 501

int map[MAXSIZE][MAXSIZE];
int pathCnt = 0; /**< 计算到某城市最短路径一共有多少条 */
int minDist = INF;
int collect[MAXSIZE] = {0};
int teams[MAXSIZE];
int maxTeam = 0;

int numOfCity, numOfRoad, sCity, eCity;

void DFS(int curCity, int curDist, int numTeam);
void DFS(int curCity, int curDist, int numTeam)
{
    if(curCity == eCity)  /**< 如果到了目标城市 */
    {
        if(curDist < minDist)
        {
            minDist = curDist;
            pathCnt = 1;
            maxTeam = numTeam;
        }
        else if(curDist == minDist)
        {
            pathCnt++;
            if(maxTeam < numTeam)
            {
                maxTeam = numTeam;
            }
        }
        return;
    }

    collect[curCity] = 1;

    int i;
    for(i=0; i<numOfCity; i++)
    {
        if(collect[i]==0 && map[curCity][i]!=INF)
        {
            DFS(i, curDist+map[curCity][i], numTeam+teams[i]);
        }
    }

    collect[curCity] = 0;
}

int main()
{
    int i, j;
    scanf("%d %d %d %d", &numOfCity, &numOfRoad, &sCity, &eCity);

    for(i=0; i<numOfCity; i++)
    {
        scanf("%d", &teams[i]);
    }

    for(i=0; i<numOfCity; i++)
    {
        for(j=0; j<numOfCity; j++)
        {
            map[i][j] = INF; /**< 邻接矩阵初始化为无穷大,即城市间都不连通 */
        }
    }

    for(i=0; i<numOfRoad; i++)
    {
        int x, y, z;
        scanf("%d %d %d", &x, &y, &z);
        map[x][y] = map[y][x] = z; /**< 注意是双向图,需要双向赋值 */
    }
    DFS(sCity, 0, teams[sCity]);
    printf("%d %d", pathCnt, maxTeam);
    system("pause");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值