SSL_1731【非常计划】
作者:互联网
非常计划
题目
教主开启了时光隧道来到了公元前30世纪(教主果然牛,大家卧倒= =),准备前往埃及。在他的地图上,有N个城市,我们已知他目前处在城市1,埃及在城市N. (XXX:埃及是一个城市么= =||)每一条道路都是单向的。我们还知道,从I城市到J城市需要D[I,J]的花费。教主想走一条从城市1到城市N花费最少的一条路,教主是一个喜欢思考的小盆友,他还希望你能告诉他花费最少的路径共有多少条。
Input
输入第一行为两个空格隔开的数N,E,表示这张地图里有多少个城市及有多少边的信息。
下面E行,每行三个数I、J、C,表示从I城市到J城市有道路相连且花费为C.(注意,数据提供的边信息可能会重复,不过保证I<>J,1<=I,J<=N)。
Output
包含两个数,分别是最少花费和花费最少的路径的总数。
Sample Input
5 4
1 5 4
1 2 2
2 5 2
4 1 1
Sample Output
4 2
解析
在dij的板子上加一句就能过
但是看到时间:
惨不忍睹的1946ms
想加一个堆优化,打开排名
什么?第四优解?我觉得够了(逃)
code:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,x,y,z,k,a[2010][2010],w[2010],s[2010];
bool u[2010];
int main()
{
memset(w,0x7f7f7f7f,sizeof(w));
memset(a,0x7f7f7f7f,sizeof(a));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
a[x][y]=min(a[x][y],z);
}
w[1]=0;
s[1]=1;
for(int i=1;i<=n;i++)
{
k=0;
for(int j=1;j<=n;j++)if(!u[j]&&w[j]<w[k])k=j;
u[k]=1;
for(int j=1;j<=n;j++)
{
if(!u[j]&&w[k]+a[k][j]<w[j])w[j]=w[k]+a[k][j],s[j]=s[k];//重置
else if(!u[j]&&w[k]+a[k][j]==w[j])s[j]+=s[k];//增加
}
}
if(w[n]==-16843010)
{
printf("No answer");//居然还真有这个点
return 0;
}
printf("%d %d",w[n],s[n]);//输出
return 0;
}
标签:1731,教主,城市,d%,花费,SSL,int,计划,2010 来源: https://blog.csdn.net/zhanglili1597895/article/details/112132999