PAT:1003. Emergency (25) AC
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXV=510;
const int INF=0x3fffffff;
int n,m,c1,c2;
bool vis[MAXV];
int G[MAXV][MAXV]; //城市间距离
int weight[MAXV]; //每个城市的救援人数
int d[MAXV]; //最短距离
int w[MAXV]; //可以带的最多人
int num[MAXV]; //最短路径条数
void Dijkstra(int s)
{
memset(num,0,sizeof(num));
memset(vis,false,sizeof(vis));
fill(d,d+MAXV,INF);
memset(w,0,sizeof(w));
d[s]=0; //本城市到本城市距离为0
w[s]=weight[s]; //自己城市的救援队人数
num[s]=1; //到自己城市最短路径为1条
for(int i=0 ; i<n ; ++i)
{
int MIN=INF,u=-1;
for(int j=0 ; j<n ; ++j) //找最小d
{
if(vis[j]==false && MIN>d[j])
{
MIN=d[j];
u=j;
}
}
if(-1==u) //图有不连通的部分
return;
vis[u]=true;
for(int v=0 ; v<n ; ++v)
{
if(vis[v]==false && G[u][v]!=INF)
{
if(d[v]>d[u]+G[u][v])
{
d[v]=d[u]+G[u][v]; //更新最短距离
w[v]=w[u]+weight[v]; //更新救援人数
num[v]=num[u]; //【warning】到新最短路径,当然是u的条数
}
else if(d[v]==d[u]+G[u][v])
{
num[v]+=num[u]; //【warning】最短路径数为u的条数+v的条数
if(w[v]<w[u]+weight[v])
{
w[v]=w[u]+weight[v]; //路径相同,存入最多的救援队数量
}
}
}
}
}
}
int main()
{
fill(G[0],G[0]+MAXV*MAXV,INF);
scanf("%d%d%d%d",&n,&m,&c1,&c2);
for(int i=0 ; i<n ; ++i) //存入每个城市救援队人数
scanf("%d",&weight[i]);
for(int i=0 ; i<m ; ++i) //存入城市间距离
{
int u,v;
scanf("%d%d",&u,&v);
scanf("%d",&G[u][v]);
G[v][u]=G[u][v];
}
Dijkstra(c1);
printf("%d %d\n",num[c2],w[c2]);
return 0;
}