其他分享
首页 > 其他分享> > SSL_1731【非常计划】

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