PAT 甲级 1003 Emergency (25 分)

人生中第一个Dijkstra,学习Dijkstra算法+看柳神代码+自己重新写一遍+debug总共做了一下午,离散数据结构没学好的痛!

柳神代码:https://www.liuchuo.net/archives/2359
柳神做的这道题不仅能求出目标城市的最短路径条数和集合的救援队数,而且求出了其余所有城市的这两个值,令人赞叹!

我的代(fu)码(zhi)

#include<iostream>
#include<algorithm>
using namespace std;
#define max 99999999
int main()
{
	int n,m,c1,c2,u,minn,i,j,k,a,b,c;
	int e[510][510];
	int dist[510];
	int ways[510];                //用来存放从c1到任意城市的最短路径条数
	int team[510],allteam[510]={0};    //allteam数组用来存放任意城市能集合的最大救援队数
	bool v[510];
	fill(e[0],e[0]+510*510,max);
	fill(dist,dist+510,max);
	scanf("%d%d%d%d",&n,&m,&c1,&c2);
	for(i=0;i<n;i++)scanf("%d",&team[i]);
	for(i=0;i<m;i++)
	{
		scanf("%d%d%d",&a,&b,&c);
        e[a][b]=e[b][a]=c;
    }
	dist[c1]=0;         //源头到自己的distance是0
	ways[c1]=1;       //从源头到源头自己只有一条最短路径,所以是1
    allteam[c1]=team[c1];    //对源头自己而言,显然
	for(i=0;i<n;i++)
	{
		u=-1;
		minn=max;
		for(j=0;j<n;j++)
		{
			if(v[j]==false&&dist[j]<minn)     //
			{
				u=j;                   //第一次循环时,u=c1
				minn=dist[j];
			}
		}
		if(u==-1)break;
		v[u]=true;
        for(k=0;k<n;k++) 
		{
            if(v[k]==false&&e[u][k]!=max)
			{
                if(dist[u]+e[u][k]<dist[k])
				{
                    dist[k]=dist[u]+e[u][k];
                    ways[k]=ways[u];
                    allteam[k]=allteam[u]+team[k];
                } 
				else if(dist[u]+e[u][k]==dist[k])     //如果此判断成立,说明找到了一条到k城的新最短路径,即经过u城到k城
				{
                    ways[k]+=ways[u];    //故需要在原本的ways[k]上加上ways[u]
                    if(allteam[u]+team[k]>allteam[k])allteam[k]=allteam[u]+team[k];
                }
            }
	    }
    }
    cout<<ways[c2]<<' '<<allteam[c2];
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值