题目描述

“RP餐厅”的员工素质就是不一般,在齐刷刷的算出同一个电话号码之后,就准备让HZH,TZY去送快餐了,他们将自己居住的城市画了一张地图,已知在他们的地图上,有N个地方,而且他们目前处在标注为“1”的小镇上,而送餐的地点在标注为“N”的小镇。(有点废话)除此之外还知道这些道路都是单向的,从小镇I到J需要花费D[I,J]的时间,为了更高效快捷的将快餐送到顾客手中,

他们想走一条从小镇1到小镇N花费最少的一条路,但是他们临出发前,撞到因为在路上堵车而生气的FYY,深受启发,不能仅知道一条路线,万一。。。,于是,他们邀请FYY一起来研究起了下一个问题:这个最少花费的路径有多少条?

输入输出格式

输入格式:

输入文件第一行为两个空格隔开的数N,E,表示这张地图里有多少个小镇及有多少边的信息。

下面E行,每行三个数I、J、C,表示从I小镇到J小镇有道路相连且花费为C.(注意,数据提供的边信息可能会重复,不过保证I<>J,1<=I,J<=n)。

输出格式:

输出文件包含两个数,分别是最少花费和花费最少的路径的总数.

两个不同的最短路方案要求:路径长度相同(均为最短路长度)且至少有一条边不重合。

若城市N无法到达则只输出一个(‘No answer’);

输入输出样例

输入样例#1: 复制

5 4
1 5 4
1 2 2
2 5 2
4 1 1
输出样例#1: 复制

4 2

说明

对于30%的数据 N<=20;

对于100%的数据 1<=N<=2000,0<=E<=N*(N-1), 1<=C<=10.

//就是个最短路计数问题,因为最大的数据是个完全图,所以用适合稠密图的dijkstra来做
//因为可能会有边权不同的重边,所以开个二维数组记录u->v的这条边有没有加入过,权值是多少 (空间开的下二维数组)
//如果新的重边的权值w比之前的w小,则新加这条边,否则会影响最短路长度
//如果w>=之前的w,则continue,因为加入之后不会影响最短路长度,而且满足了题目中要求至少有一条边不重。 //这道题用二维数组要比邻接表简单,二维数组直接取个min()就可以了。 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std; const int N=2e3+;
const int M=4e6+;
const int INF=; int n,m;
int ans_min,ans_sum;
int head[N],num_edge;
int sum[N];
bool visited[N];
int len[N][N];
struct STA
{
int id,dis;
bool operator < (const STA &A) const
{
return this->dis>A.dis;
}
}sta[N];
struct Edge
{
int v,w,nxt;
}edge[M];
priority_queue<STA> heap; int read()
{
char c=getchar();int num=;
for(;!isdigit(c);c=getchar());
for(;isdigit(c);c=getchar())
num=num*+c-'';
return num;
} void add_edge(int u,int v,int w)
{
edge[++num_edge].v=v;
edge[num_edge].w=w;
edge[num_edge].nxt=head[u];
head[u]=num_edge;
} void dijkstra()
{
for(int i=;i<=n;++i)
{
sta[i].id=i;
sta[i].dis=INF;
}
sta[].dis=;
sum[]=;
heap.push(sta[]);
int now,ans_min=INF;
while(!heap.empty())
{
now=heap.top().id,heap.pop();
if(visited[now])
continue;
visited[now]=;
for(int i=head[now],v;i;i=edge[i].nxt)
{
v=edge[i].v;
if(sta[v].dis>sta[now].dis+edge[i].w)
{
sta[v].dis=sta[now].dis+edge[i].w;
sum[v]=sum[now];
if(!visited[v])
{
heap.push(sta[v]);
}
}
else
if(sta[v].dis==sta[now].dis+edge[i].w)
sum[v]+=sum[now];
}
}
} int main()
{
memset(len,INF,sizeof(len));
n=read(),m=read();
for(int i=,u,v,w;i<=m;++i)
{
u=read(),v=read(),w=read();
if(len[u][v]<=w)
continue;
len[u][v]=w;
add_edge(u,v,w);
}
dijkstra();
if(sta[n].dis==INF)
puts("No answer");
else
printf("%d %d",sta[n].dis,sum[n]);
return ;
}

最新文章

  1. Angular2入门系列教程1-使用Angular-cli搭建Angular2开发环境
  2. Knockout 官网翻译
  3. 【转】ArcGIS地图缓存制作简介
  4. NYOJ题目1049自增自减
  5. perl 简单学习,安装perl模块
  6. UVa 10020 (最小区间覆盖) Minimal coverage
  7. Php 笔记4-----php 细节知识
  8. open/write/read
  9. 函数buf_LRU_block_remove_hashed_page
  10. PAT 天梯赛 L2-002 链表去重
  11. [编织消息框架][网络IO模型]aio
  12. 两行 CSS 代码实现 PNG 任意颜色赋色技术
  13. Laravel的unique和exists验证规则的优化
  14. BZOJ2329 HNOI2011 括号修复 splay+贪心
  15. hdu 5120(2014北京—求圆相交)
  16. mac air中编译安装swoole
  17. 通用Logging框架设计
  18. MYSQL InnoDB Cluster
  19. BZOJ2662[BeiJing wc2012]冻结——分层图最短路
  20. 注册页面手机验证码无跳转接收[html+js+ajax+php]

热门文章

  1. PowerBuilder学习笔记之2PowerScript语言(三)
  2. ionic开发遇到的问题总结
  3. 怎样获取全局对象 window
  4. shellexecute的使用和X64判断
  5. 在论坛中出现的比较难的sql问题:38(字符拆分 字符串检索问题)
  6. asp.net后台或前端获取TemplateField绑定的文本
  7. 使用async和await的异步编程
  8. 利用WkHtmlToPdf,把H5 转成PDF
  9. Ubuntu install android studio
  10. 数据结构之链表(LinkedList)(二)