HDU 3191 次短路长度和条数
http://www.cnblogs.com/wally/archive/2013/04/16/3024490.html
http://blog.csdn.net/me4546/article/details/6584448
维护最短路长度d[i][0]和次短路d[i][1],最短路条数dp[i][0]和次短路dp[i][1]
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std; #define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define MAXN 5010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pqueue priority_queue
#define INF 0x3f3f3f3f struct Edge
{
int v,w;
};
vector<Edge> g[];
struct node
{
int v,dist;
int mark;//标记,0为最短路,1为次短路;
bool operator < (const node &p) const
{
if(p.dist != dist)
return p.dist<dist; return p.v<v;//这儿如果不按顶点的大小排序,就wa了。
}
}; int n,m,s,e;
int dist[][];
int dp[][];
bool vis[][];
//dp[i][0]表示到达点i最短的路有多少条,dp[i][1]表示次短的条数
//dist[i][0]表示到达点i最短路的长度,dist[i][1]表示次短路的长度
/*
用v去松驰u时有四种情况 (设当前dist[v][cas])
情况1:dist[v][cas]+w(v,u)<dist[u][0],找到一个更短的距离,则把原来最短的距离作为次短的距离,同时更新最短的.即
dist[u][1]=dist[u][0]
dist[u][0]=dist[v][cas]+w(v,u);
dp[u][1]=dp[u][0]
dp[u][0]=dp[v][cas],
把node(dist[u][0],u,0)和node(dist[u][1],u,1)放入队列
情况2:dist[v][cas]+w(v,u)==dist[u][0],找到一条新的相同距离的最短路,则dp[u][0]+=dp[v][cas],其他不用更新,也不入队
情况3:dist[v][cas]+w(v,u)<dist[u][1],不可以更新最短距离,但可以更新次短的,则更新dist[u][1]和dp[u][1]
dist[u][1]=dist[v][cas]+w(v,u);
dp[u][1]=dp[v][cas];
把node(dist[u][1],u,1)放入队列
情况4:dist[v][cas]+w(v,u)==dist[u][1] 找到一条新的相同距离的次短路,则dp[u][1]+=dp[v][cas],其他不更新。
*/ void dijkstra(int start,int end)
{
for(int i=;i<n;i++)
{
dist[i][]=dist[i][]=INF;
}
memset(dp,,sizeof(dp));
memset(vis,false,sizeof(vis));
priority_queue<node> Q;
node p,q;
dist[start][]=;
dp[start][]=;
p.dist=,p.mark=,p.v=start;
Q.push(p);
while(!Q.empty())
{
p=Q.top();
Q.pop();
if(vis[p.v][p.mark]) continue;
//if(dist[p.v][p.mark]!=p.dist)continue;
vis[p.v][p.mark]= true;
for(int i=;i<g[p.v].size();i++)
{
int v=g[p.v][i].v;
int w=g[p.v][i].w;
if(!vis[v][] && p.dist+w <dist[v][])
{
//可能为次短路
if(dist[v][]!=INF)
{
q.v=v,q.dist=dist[v][],q.mark=;
dist[v][]=dist[v][];
dp[v][]=dp[v][];
Q.push(q);
}
dist[v][]=p.dist+w;
dp[v][]=dp[p.v][p.mark];
q.v=v,q.dist=dist[v][],q.mark=;
Q.push(q);
}
else if(!vis[v][] && p.dist+w==dist[v][])
{
dp[v][]+=dp[p.v][p.mark];
}
else if(!vis[v][] && p.dist+w<dist[v][])
{
dist[v][]=p.dist+w;
dp[v][]=dp[p.v][p.mark];
q.dist=dist[v][],q.v=v,q.mark=;
Q.push(q);
}
else if(!vis[v][]&&p.dist+w==dist[v][])
{
dp[v][]+=dp[p.v][p.mark];
}
}
}
} int main(){
while(~scanf("%d%d%d%d",&n,&m,&s,&e))
{
for(int i=;i<n;i++)g[i].clear();
for(int i=;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
Edge p;
p.v=v,p.w=w;
g[u].push_back(p);
}
dijkstra(s,e);
printf("%d %d\n",dist[e][],dp[e][]);
}
return ;
}
HDU 3191 次短路长度和条数的更多相关文章
- hdu 3191 次短路的长度和个数
http://acm.hdu.edu.cn/showproblem.php?pid=3191 求次短路的长度和个数 相关分析在这里http://blog.csdn.net/u012774187/art ...
- HDU 1688 Sightseeing&HDU 3191 How Many Paths Are There(Dijkstra变形求次短路条数)
Sightseeing Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU1688-POJ3463-Sightseeing(求次短路的条数)
题意 求出最短路和次短路的条数,当次短路比最短路长度小1时,输出条数之和,反之输出最短路条数. 题解 dis1[],cnt1[],dis2[],cnt2[] 分别表示最短路的长度和条数,次短路的长度 ...
- HDU 1688 Sightseeing 【输出最短路+次短路条数】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题目大意:给n个点,m条有向边.再给出起点s, 终点t.求出s到t的最短路条数+次短路条数. 思 ...
- HDU 3416 Marriage Match IV (求最短路的条数,最大流)
Marriage Match IV 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/Q Description Do not si ...
- hdu 3191 How Many Paths Are There (次短路径数)
How Many Paths Are There Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- HDU3191 【输出次短路条数】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3191 How Many Paths Are There Time Limit: 2000/1000 M ...
- 最短路和次短路的条数(dijstra算法或spfa算法)POJ3463
http://poj.org/problem?id=3463 Sightseeing Time Limit: 2000MS Memory Limit: 65536K Total Submissio ...
- POJ---3463 Sightseeing 记录最短路和次短路的条数
Sightseeing Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9247 Accepted: 3242 Descr ...
随机推荐
- [Maven实战-许晓斌]-[第二章]-2.2基于UNIX系统安装maven
>> >> >>3
- jxl获取excel中的合并的单元格(主要是方法介绍)
Range[] rangeCells = sheet.getMergedCells();// 返回sheet中合并的单元格数组 for (Range r : rangeCells) {//对数组遍历拿 ...
- easyui里面的加载tree的两种方式
第一种: 使用EasyUI中Tree 符合EasyUI中Tree的Json格式,我们先看一下,格式是如何的 [{ "id":1, "text":"My ...
- Python3之文本操作
文件操作示例分析: 文件操作一般要经历三个步骤: 打开文件 操作文件 关闭文件 读取操作示例: >>>f = open('test.txt', 'r') # 打开文件test.txt ...
- [jvm]运行时数据区域详解
了解虚拟机是怎么使用内存的,有助于我们解决和排查内存泄漏和溢出方面的问题.详解java虚拟机内存的各个区域,分析这些区域的作用服务对象以及可能发生的问题. 一.运行时数据区域 java虚拟机在执行ja ...
- ssh访问流程
SSH是英文Secure Shell的简写形式.通过使用SSH,你可以把所有传输的数据进行加密,这样"中间人"这种攻击方式就不可能实现了,而且也能够防止DNS欺骗和IP欺骗.使用S ...
- java架构师之路,享学课堂VIP课程视频下载
享学课堂并发编程:百度网盘 链接:https://pan.baidu.com/s/10O8oXC0yNRArUh3WKkXayg 提取码:o01s 更多视频获取方式请留言
- docker 创建容器的时候的坑
其实这个题目的话,对于我后面陈述的问题发生的本身并没有太多的联系,但是因为是在docker创建容器的操作之内发生的,所以记录以下 因为网上有些文章有些作者喜欢使用git的命令窗体,说实在的,公司里面用 ...
- Springboot第三篇:与前端fetch通信(关于前端传输json数据上传文件等等前后端的处理)
关于前端接口传递的方法,推荐按以下使用: 若要在服务器上创建资源,推荐使用POST方法 若要检索某个资源,推荐使用GET方法 若要更新资源,推荐使用PUT方法 若要删除某个资源,推荐使用DELETE方 ...
- c# 引用类型对象的深拷贝
c#中的对象大体分为值类型和引用类型,值类型大致包括 int, struct等,引用类型大致包括 自定义Class,object 等.string属于特殊的引用类型,不在本文的讨论之内. 值类型直接存 ...