人生中第一个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;
}