给定一个无向带权网络,无负边,无重边和自环,每个顶点有一个正数权值。首先求特定原点s到终点d的最短路的个数;然后求所有最短路中顶点权值a[i]之和最大的那条,输出这条路径。

可用dijkstra算法求出所有最短路,用一个pathNum[u]数组记录从s到u的最短路的个数,查找链path[u]保存了到u为止使顶点权值a[i]之和最大的那条路径,sum[u]保存了这条路径的顶点权值和。

对于提交后的第3个测试点,注意更新新引入顶点u的邻居v的距离值dis[v]时,sum[v]无条件更新为sum[u]+a[v],因为要先满足最短路这个条件,得到的顶点才有意义。最短路更新,则sum要重新计算。

参考了博客 http://blog.csdn.net/tc_to_top/article/details/51427223

 #include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <stack>
#include <cmath>
#define RINT(V) scanf("%d", &(V))
#define FREAD() freopen("in.txt", "r", stdin)
#define REP(N) for(int i=0; i<(N); i++)
#define REPE(N) for(int i=1; i<=(N); i++)
#define PINT(N) printf("%d", (N))
#define PSTR(S) printf("%s", S)
#define RSTR(S) scanf("%s", S)
#define pn() printf("\n")
#define pb(V) push_back(V)
#define CLEAR(A, V) memset((A), (V), sizeof(A))
using namespace std;
typedef long long ll;
const int MAX_N = ;
const int INF = 0x3fffffff; int n, m, s, d;
int a[MAX_N]; int V;
int G[MAX_N][MAX_N];//邻接矩阵,无边是INF, 自己到自己是0
int dis[MAX_N];//单源最短路数组
int vis[MAX_N];
int path[MAX_N], pathNum[MAX_N];
int sum[MAX_N]; int shortest(){
int minn = INF;
int rt = -;
for(int v=; v<n; v++){
if(v == s) continue;
if(!vis[v] && dis[v] < minn){
minn = dis[v];
rt = v;
}
}
return rt;
} void dijkstra(){
for(int v=; v<n; v++){
if(G[s][v] != INF && v != s){
dis[v] = G[s][v];//一步直达
path[v] = s;
pathNum[v] = ;
sum[v] = a[s] + a[v];
}
}
path[s] = -;
pathNum[s] = ;
vis[s] = ;
sum[s] = a[s];
dis[s] = ;
while(){
int u = shortest();//select the next vertex
if(u == -) break;//no vertex left
//cout << "choose " << u << endl;
vis[u] = ;
for(int v=; v<n; v++){//update priority
if(vis[v]) continue;//只考虑Tk以外,即最短路尚未确定的点
if(dis[v] > dis[u] + G[u][v]){
pathNum[v] = pathNum[u];
dis[v] = dis[u] + G[u][v];
path[v] = u;//记录前驱
sum[v] = sum[u] + a[v];//更新顶点上的权值和
}else if(dis[v] == dis[u] + G[u][v]){//这部分是关键,同值不同解
//cout << "same " << u << endl;
pathNum[v] += pathNum[u];//|Tv| += |Tu| 这一步是关键
if(sum[v] < sum[u] + a[v]){
sum[v] = sum[u] + a[v];
path[v] = u;
}
}
//cout << "path[" << v << "] = " << path[v] << endl;
}
}
} void init(){
for(int u=; u<n; u++){
for(int v=; v<n; v++){
G[u][v] = INF;
}
G[u][u] = ;
dis[u] = INF;
}
CLEAR(path, -);
CLEAR(pathNum, );
CLEAR(sum, );
CLEAR(vis, );
} int main()
{
FREAD();
scanf("%d%d%d%d", &n, &m, &s, &d);
init();
REP(n) RINT(a[i]);
REP(m){
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
G[u][v] = min(G[u][v], w);//其实没有重边
G[v][u] = G[u][v];//邻接矩阵
} dijkstra();//s为源, d为目的地
printf("%d %d\n", pathNum[d], sum[d]); //输出路径
stack<int> sta;
int cur = d;
sta.push(cur);
while(cur != s){
cur = path[cur];
sta.push(cur);
}
while(sta.size() > ){
printf("%d ", sta.top());
sta.pop();
}
printf("%d", sta.top());
return ;
}

【PAT L2-001】最短路计数的更多相关文章

  1. 【SPFA】 最短路计数

    最短路计数 [问题描述]   给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. [输入格式]   输入第一行包含2个正整数N,M,为图的顶点数与边数. ...

  2. P1144 最短路计数

    P1144 最短路计数 题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 输入第一行包含2个正整数N,M,为图的顶 ...

  3. 洛谷P1144最短路计数题解

    最短路计数 此题还是寻找从1到i点总共有几个最短路且每条边的边长为1,对于这种寻找最短路的个数,我们可以反向搜索,即先用\(SPFA\)预处理出所有点的最短路,然后我们反向记忆化搜索,可以用\(sum ...

  4. 洛谷P1144 最短路计数(SPFA)

    To 洛谷.1144 最短路计数 题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 输入第一行包含2个正整数N,M ...

  5. 2018.11.05 NOIP模拟 规避(最短路计数)

    传送门 正难则反. 考虑计算两人相遇的方案数. 先正反跑一遍最短路计数. 然后对于一条在最短路上的边(u,v)(u,v)(u,v),如果(dis(s,u)*2<total&&di ...

  6. 洛谷 P1144 最短路计数 解题报告

    P1144 最短路计数 题目描述 给出一个\(N\)个顶点\(M\)条边的无向无权图,顶点编号为\(1-N\).问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 第一行包含2个正 ...

  7. BZOJ1632: [Usaco2007 Feb]Lilypad Pond SPFA+最短路计数

    Description 为了让奶牛们娱乐和锻炼,农夫约翰建造了一个美丽的池塘.这个长方形的池子被分成了M行N列个方格(1≤M,N≤30).一些格子是坚固得令人惊讶的莲花,还有一些格子是岩石,其余的只是 ...

  8. 1491. [NOI2007]社交网络【最短路计数】

    Description 在社交网络(socialnetwork)的研究中,我们常常使用图论概念去解释一些社会现象.不妨看这样的一个问题. 在一个社交圈子里有n个人,人与人之间有不同程度的关系.我们将这 ...

  9. 洛谷P1144 最短路计数 及其引申思考

    图论题目练得比较少,发一道spfa的板子题目- 题目:P1144 题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: ...

随机推荐

  1. [iOS] Baritem 添加一项

    不是拖拽,而是在设计栏的属性设置里面.

  2. OpenXML - 如何导出List<DataModel>到Excel -- Part 1

    最近这几天研究OpenXML: 这是Open XML的一些介绍: Open XML 介绍:http://baike.baidu.com/view/1201978.htm 下载:http://www.m ...

  3. python标准库基础之mmap:内存映射文件

    #作用:建立内存映射文件而不是直接读取内容文本信息内容:如下(名称是text.txt) Lorem ipsum dolor sit amet, consectetuer adipiscing elit ...

  4. (转)iOS7界面设计规范(13) - UI基础 - 与iOS的系统整合

    突然就到了周日傍晚.你永远不会知道自己的生活在接下来的一周当中能够发生多少变化:各种不可预知性所带来的更多是快感还是焦虑与不安,冷暖自知.相比之下,白天工作当中那些需求列表与排期文档就显得那么可爱了, ...

  5. 使用java对sql server进行增删改查

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...

  6. asp.net 正则表达式

    在平时的开发中常常用到替换法:  普通的字符串替换可以使用string.replace(string,string),但是比较难解决HTML文本的替换. 经我几番查找,终也找出解决办法:正则匹配替换. ...

  7. angular 指令梳理 —— 前端校验

    angular js内置校验的扩展 校验成功则 scope.formName.$valid=true 校验失败  元素的class: ng-invalid 成功:.ng-valid /** * 校验指 ...

  8. 查看kafka的group.id

    kafka/config目录下的consumer.properties中可以看到

  9. mysql中常用的语句整理

    mysql中常用的语句: 1:创建带自增长的主键的表 DROP TABLE IF EXISTS user_login ; CREATE TABLE user_login (   user_id INT ...

  10. winPcap_1_开篇

    什么是WinPcap WinPcap是一个基于Win32平台的,用于捕获网络数据包并进行分析的开源库. 因为有些应用程序需要直接访问网络中的数据包.也就是说,那些应用程序需要访问原始数据包,即没有被操 ...