题目翻译:
作为一个城市紧急援救队的指挥者,你得到了一个国家的特殊地图。地图上分散着几座城市,城市间用道路连接着。每个城市援救队的数量以及两座城市之间每条道路的长度已经在地图上标出。当某些城市发生了突发事件,需要你的帮助时,你的工作是带领你的队伍尽快的赶到事发现场,与此同时,召集尽可能多的在路上的队伍。
输入
每个输入文件包含一个测试实例。每个实例的第一行有四个正整数:N(<= 500)是城市的个数(城市的编号从0到N-1),M是道路的个数,C1和C2分别是你现在所在的城市以及你必须去救援的城市。下一行有N个整数,第i个整数是第i个城市中救援队的数量。然后下面有M行,每行表示一条道路。每一行有三个整数c1,c2和L,分别表示道路连接的两个城市以及道路的长度。保证C1到C2之间存在至少一条路径。
输出
对于每个测试实例,在一行中输出两个数字:C1和C2之间不同的最短路径的个数,你能聚集起来的最多的救援队数量。
一行中的所有数字必须被一个空格分隔开,在每行的结尾不允许出现空格。
样例输入
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
样例输出
2 4
以下为答案源码:
#include<iostream>
using namespace std;
#define MaxCityNum 501
#define MaxRoadLength 999999999
int ddistance[MaxCityNum][MaxCityNum],citynum,roadnum,from,to;//城市之间距离,城市数量,路的数量,出发点,目的地
int dis[MaxCityNum],teamnum[MaxCityNum],waynum[MaxCityNum],sum[MaxCityNum];//最短距离,救援队数量,最短路径数量,可收集的最大救援队数量
bool visited[MaxCityNum];//记录城市是否被访问
//Dijkstra算法找最短路径
void Dis()
{
int i,j;
for(i=0;i<citynum;i++)
{
dis[i]=ddistance[from][i];
visited[i]=false;
}
dis[from]=0;
visited[from]=true;
sum[from]=teamnum[from];
for(i=1;i<citynum;i++)
{
int u=-1;
int mindis=MaxRoadLength;
for(j=0;j<citynum;j++)
{
if(visited[j]==false&&dis[j]<mindis)
{
mindis=dis[j];
u=j;
}
}
if(u==-1) break;
visited[u]=true;
for(j=0;j<citynum;j++)
{
if((visited[j]==false)&&(dis[j]==dis[u]+ddistance[u][j]))
{
waynum[j]=waynum[j]+waynum[u];
if(sum[j]<sum[u]+teamnum[j])
{
sum[j]=sum[u]+teamnum[j];
}
}
if((visited[j]==false)&&(dis[j]>dis[u]+ddistance[u][j]))
{
dis[j]=dis[u]+ddistance[u][j];
waynum[j]=waynum[u];
sum[j]=sum[u]+teamnum[j];
}
}
}
}
int main()
{
int i,j;
int x,y,z;
cin>>citynum>>roadnum>>from>>to;
for(i=0;i<citynum;i++)
cin>>teamnum[i];
for(i=0;i<citynum;i++)
for(j=0;j<citynum;j++)
{
if(i==j)
ddistance[i][j]=0;
else
ddistance[i][j]=ddistance[j][i]=MaxRoadLength;
}
for(i=0;i<roadnum;i++)
{
cin>>x>>y>>z;
ddistance[x][y]=ddistance[y][x]=z;
}
for(i=0;i<citynum;i++)
{
visited[i]=false;
waynum[i]=1;
sum[i]=teamnum[from]+teamnum[i];
}
Dis();
cout<<waynum[to]<<" "<<sum[to];
return 0;
}