AcWing 1475. 紧急情况
原题链接
中等
作者:
leo123456
,
2020-08-25 20:06:57
,
所有人可见
,
阅读 688
#include<iostream>
#include<cstring>
using namespace std;
const int N=510;
int n,m,S,T;
int d[N][N],w[N]; //d两点之间的距离 , w每个点上的救援队数量
int dist[N],cnt[N],sum[N]; //cnt 已更新的所以到这个点最短路相同的数量,sum在最短路的条件下所以点救援队之和
bool st[N];
void dijkstra()
{
memset(dist,0x3f,sizeof dist); //规定操作
dist[S]=0,cnt[S]=1,sum[S]=w[S];
for(int i=0;i<n;i++)
{
int t=-1;
for(int j=0;j<n;j++)
if(!st[j]&&(t==-1||dist[t]>dist[j]))
t=j;
st[t]=true;
for(int j=0;j<n;j++)
if(dist[j]>dist[t]+d[t][j]) //如果有更短的最短路,就全部更新,dist,cnt为所有点到t的最短路数量,这样只能从t到j了,所以之间赋值,sum也是在最短路的条件了更新的,所以必须取这条路的救援队数量(之前多也要更新,因为这个最短)即为sum[t]+w[j];
{
dist[j]=dist[t]+d[t][j];
cnt[j]=cnt[t];
sum[j]=sum[t]+w[j];
}
else if(dist[j]==dist[t]+d[t][j])
{ //如果从t到j和之前的最短路一样长,那么最短路一样,就不需要多此一举了,因为多了一条t-》j的最短路,那么要把t->j的所以最短路加过来(可能很多条,虽然t->j只有一条, 但是其它点到t可能有很多条,),
cnt[j]+=cnt[t];
sum[j]=max(sum[j],sum[t]+w[j]); //在这很多条中取一个最大的救援队数量就可以了。
}
}
}
int main()
{
cin>>n>>m>>S>>T;
for(int i=0;i<n;i++) cin>>w[i];
memset(d,0x3f,sizeof d); //规定操作
while(m--)
{
int a,b,c;
cin>>a>>b>>c;
d[a][b]=d[b][a]=min(d[a][b],c); //习惯写法,避免有重边,有就取最短的
}
dijkstra();
cout<<cnt[T]<<' '<<sum[T]<<endl;
return 0;
}