给定一个无向带权网络,无负边,无重边和自环,每个顶点有一个正数权值。首先求特定原点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. c语言0 ‘0’ '\0'空格都是什么玩意儿

    void main() { ; '; printf("\n%d,%c",ch,ch);//按照%d就是求编号,按照字符 printf("\n[%d],[%c]" ...

  2. poj 1466 Girls and Boys(二分匹配之最大独立集)

    Description In the second year of the university somebody started a study on the romantic relations ...

  3. java多个listener监听

    java 多个listener 监听方法 在class 名称上一行添加@Listeners 括号中用逗号隔开 @Listeners({com.example.MyListener.class,com. ...

  4. [MongoDB] Remove, update, create document

    Remove: remove the wand with the name of "Doom Bringer" from our wandscollection. db.wands ...

  5. 搭建LAMP架构

    1. 为什么下载源码包需要到官网上去下载?简单说就是为了安全,如果是非官方下载的源码包,有可能被别有用心的人动过手脚. 2. 64位机器是否可以安装32位rpm包?64位机器是否可以安装32位的mys ...

  6. 开始学javascript基础

    JavaScript非常值得我们学习. 1)所有主浏览器都支持JavaScript. 2) 目前,全世界大部分网页都使用JavaScript. 3) 它可以使网页呈现各种动态效果. 4)作为一个Web ...

  7. SpinLock(自旋锁)

    SpinLock(自旋锁) SpinLock 结构是一个低级别的互斥同步基元,它在等待获取锁时进行旋转. 在多核计算机上,当等待时间预计较短且极少出现争用情况时,SpinLock 的性能将高于其他类型 ...

  8. WebApi2官网学习记录---Media Formatters

    Web API内建支持XML.JSON.BSON.和form-urlencoded的MiME type. 创建的自定义MIME类型要继承一下类中的一个: MediaTypeFormatter 这个类使 ...

  9. windows程序消息机制(Winform界面更新有关)--转

    1. Windows程序消息机制 Windows GUI程序是基于消息机制的,有个主线程维护着消息泵.这个消息泵让windows程序生生不息. Windows程序有个消息队列,窗体上的所有消息是这个队 ...

  10. Struts2+Spring3+Hibernate3+Maven构建(基于Eclipse)

    长时间不做后台了,整理一下资料,以便翻阅. Eclipse.JDK安装略…… Maven下载地址:http://maven.apache.org/download.cgi 版本比较新的Eclipse基 ...