hdu3191题意:求出次短路的长度和条数

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int MAXN=55;
const int inf=1<<30;
struct Edge{
int v,w;
};
vector<Edge>vet[MAXN];
struct Node{
int v,dist;
int mark;//标记,1为最短路,2为次短路;
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[MAXN][3];
int dp[MAXN][3];
bool visited[MAXN][3];
//dp[i][1]表示到达点i最短的路有多少条,dp[i][2]表示次短的条数
//dist[i][1]表示到达点i最短路的长度,dist[i][2]表示次短路的长度
/*
用v去松驰u时有四种情况 (设当前dist[v][cas])
情况1:dist[v][cas]+w(v,u)<dist[u][1],找到一个更短的距离,则把原来最短的距离作为次短的距离,同时更新最短的.即
dist[u][2]=dist[u][1]
dist[u][1]=dist[v][cas]+w(v,u);
dp[u][2]=dp[u][1]
dp[u][1]=dp[v][cas],
把Node(dist[u][1],u,1)和Node(dist[u][2],u,2)放入队列
情况2:dist[v][cas]+w(v,u)==dist[u][1],找到一条新的相同距离的最短路,则dp[u][1]+=dp[v][cas],其他不用更新,也不入队
情况3:dist[v][cas]+w(v,u)<dist[u][2],不可以更新最短距离,但可以更新次短的,则更新dist[u][2]和dp[u][2]
dist[u][2]=dist[v][cas]+w(v,u);
dp[u][2]=dp[v][cas];
把Node(dist[u][2],u,2)放入队列
情况4:dist[v][cas]+w(v,u)==dist[u][2] 找到一条新的相同距离的次短路,则dp[u][2]+=dp[v][cas],其他不更新。
*/ void Dijkstra(int start,int end){
for(int i=0;i<n;i++){
dist[i][1]=dist[i][2]=inf;
}
memset(dp,0,sizeof(dp));
memset(visited,false,sizeof(visited));
priority_queue<Node>Q;
Node p,q;
dist[start][1]=0;
dp[start][1]=1;
p.dist=0,p.mark=1,p.v=start;
Q.push(p);
while(!Q.empty()){
p=Q.top();
Q.pop();
if(visited[p.v][p.mark])continue;
//if(dist[p.v][p.mark]!=p.dist)continue;
visited[p.v][p.mark]=true;
for(int i=0;i<vet[p.v].size();i++){
int v=vet[p.v][i].v;
int w=vet[p.v][i].w;
if(!visited[v][1]&&p.dist+w<dist[v][1]){
//可能为次短路
if(dist[v][1]!=inf){
q.v=v,q.dist=dist[v][1],q.mark=2;
dist[v][2]=dist[v][1];
dp[v][2]=dp[v][1];
Q.push(q);
}
dist[v][1]=p.dist+w;
dp[v][1]=dp[p.v][p.mark];
q.v=v,q.dist=dist[v][1],q.mark=1;
Q.push(q);
}else if(!visited[v][1]&&p.dist+w==dist[v][1]){
dp[v][1]+=dp[p.v][p.mark];
}else if(!visited[v][2]&&p.dist+w<dist[v][2]){
dist[v][2]=p.dist+w;
dp[v][2]=dp[p.v][p.mark];
q.dist=dist[v][2],q.v=v,q.mark=2;
Q.push(q);
}else if(!visited[v][2]&&p.dist+w==dist[v][2]){
dp[v][2]+=dp[p.v][p.mark];
}
}
}
} int main(){
while(~scanf("%d%d%d%d",&n,&m,&s,&e)){
for(int i=0;i<n;i++)vet[i].clear();
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
Edge p;
p.v=v,p.w=w;
vet[u].push_back(p);
}
Dijkstra(s,e);
printf("%d %d\n",dist[e][2],dp[e][2]);
}
return 0;
}

hdu1688

题意:求出最短路的条数比最短路大1的次短路的条数和,基本和上题一样,只是最后多了一个判断是否dist[e][1]+1==dist[e][2];

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int MAXN=1000+10;
const int inf=1<<30;
struct Edge{
int v,w;
};
vector<Edge>vet[MAXN];
struct Node{
int v,dist;
int mark;
bool operator < (const Node &p)const {
return p.dist<dist;
}
};
int dist[MAXN][3];
int dp[MAXN][3];
bool visited[MAXN][3];
int n,m,s,e; void Dijkstra(int start,int end){
for(int i=1;i<=n;i++){
dist[i][1]=dist[i][2]=inf;
}
memset(visited,false,sizeof(visited));
memset(dp,0,sizeof(dp));
dist[start][1]=0;
dp[start][1]=1;
priority_queue<Node>Q;
Node p,q;
p.dist=0,p.mark=1,p.v=start;
Q.push(p);
while(!Q.empty()){
p=Q.top();
Q.pop();
if(visited[p.v][p.mark])continue;
visited[p.v][p.mark]=true;
for(int i=0;i<vet[p.v].size();i++){
int v=vet[p.v][i].v;
int w=vet[p.v][i].w;
if(!visited[v][1]&&p.dist+w<dist[v][1]){
if(dist[v][1]!=inf){
dist[v][2]=dist[v][1];
dp[v][2]=dp[v][1];
q.v=v,q.dist=dist[v][2],q.mark=2;
Q.push(q);
}
dist[v][1]=p.dist+w;
dp[v][1]=dp[p.v][p.mark];
q.dist=dist[v][1],q.v=v,q.mark=1;
Q.push(q);
}else if(!visited[v][1]&&p.dist+w==dist[v][1]){
dp[v][1]+=dp[p.v][p.mark];
}else if(!visited[v][2]&&p.dist+w<dist[v][2]){
dist[v][2]=p.dist+w;
dp[v][2]=dp[p.v][p.mark];
q.v=v,q.dist=dist[v][2],q.mark=2;
Q.push(q);
}else if(!visited[v][2]&&p.dist+w==dist[v][2]){
dp[v][2]+=dp[p.v][p.mark];
}
}
}
} int main(){
int _case;
scanf("%d",&_case);
while(_case--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)vet[i].clear();
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
Edge p;
p.v=v,p.w=w;
vet[u].push_back(p);
}
scanf("%d%d",&s,&e);
Dijkstra(s,e);
if(dist[e][1]+1==dist[e][2]){
printf("%d\n",dp[e][1]+dp[e][2]);
}else
printf("%d\n",dp[e][1]);
}
return 0;
}

hdu3191+hdu1688(求最短路和次短路条数,模板)的更多相关文章

  1. POJ 3463 最(次)短路条数

    Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9497   Accepted: 3340 Descr ...

  2. HDU3191 【输出次短路条数】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3191 How Many Paths Are There Time Limit: 2000/1000 M ...

  3. hdu1688(dijkstra求最短路和次短路)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题意:第k短路,这里要求的是第1短路(即最短路),第2短路(即次短路),以及路径条数,最后如果最 ...

  4. 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 ...

  5. COJ 0579 4020求次短路的长度

    4020求次短路的长度 难度级别:C: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 在一个地图上共有N个路口(编号分别为1到N),R条道路( ...

  6. spfa求次短路

    思路:先算出每个点到1的最短路d1[i],记录下路径,然后枚举最短路上的边 删掉之后再求一遍最短路,那么这时的最短路就可能是答案. 但是这个做法是错误的,可以被卡掉. 比如根据下面的例题生成的一个数据 ...

  7. 图-用DFS求连通块- UVa 1103和用BFS求最短路-UVa816。

    这道题目甚长, 代码也是甚长, 但是思路却不是太难.然而有好多代码实现的细节, 确是十分的巧妙. 对代码阅读能力, 代码理解能力, 代码实现能力, 代码实现技巧, DFS方法都大有裨益, 敬请有兴趣者 ...

  8. POJ 2251 Dungeon Master --- 三维BFS(用BFS求最短路)

    POJ 2251 题目大意: 给出一三维空间的地牢,要求求出由字符'S'到字符'E'的最短路径,移动方向可以是上,下,左,右,前,后,六个方向,每移动一次就耗费一分钟,要求输出最快的走出时间.不同L层 ...

  9. HDU 3416 Marriage Match IV (求最短路的条数,最大流)

    Marriage Match IV 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/Q Description Do not si ...

随机推荐

  1. 【MySQL】mysql出现错误“ Every derived table must have its own alias”

    Every derived table must have its own alias 这句话的意思是说每个派生出来的表都必须有一个自己的别名 一般在多表查询时,会出现此错误. 因为,进行嵌套查询的时 ...

  2. Maven运行Selenium报错org/w3c/dom/ElementTraversal

    项目使用maven 构建,并且使用集成测试(integration-test). 在命令行中运行mvn clean deploy tomcat:undeploy时,报错: java.lang.NoCl ...

  3. 【Linux】字符转换命令expand

    这命令就是在将 [tab] 按键转成空格键: [root@www ~]# expand [-t] file 选项与参数: -t :后面可以接数字.一般来说,一个 tab 按键可以用 个空格键取代. 我 ...

  4. 站在.NET的角度学安卓的草民笔记1

    Java           ->        .NET 安卓          ->        winform/WPF 类继承Activity  ->     类继承 For ...

  5. golang学习笔记 --- goroutine

    package main import ( "fmt" "io" "io/ioutil" "net/http" &quo ...

  6. javascript中 try catch finally 的使用

    例一:function message(){ try { adddlert("Welcome guest!") } catch(err) { txt="此页面存在一个错误 ...

  7. Swift2.0语言教程之函数嵌套调用形式

    Swift2.0语言教程之函数嵌套调用形式 Swift2.0语言函数嵌套调用形式 在Swift中,在函数中还能够调用函数,从而形成嵌套调用.嵌套调用的形式往往有两种:一种是在一个函数中调用其它函数:还 ...

  8. Springboot使用junit

    1. 首先要下载配套的spring-boot-starter-test包,注意版本要对应. compile("org.springframework.boot:spring-boot-sta ...

  9. 浅谈cocos2dx(18) 中工厂模式

    ----我的生活.我的点点滴滴! ! cocos2d-x中也有工厂模式.何为工厂模式,顾名思义就是用来产生产品的,工厂就是用来创建其它类对象的类,我们把这个创建其它类对象的类叫做工厂类.而这些被创建的 ...

  10. django 模板语言入门详解

    django 模板语言所解决的问题域: 1.动态生成html文件 2.是上这个模板语言用可用于生成任何形式的文本文件 从一个不用模板语言生成html的例子看模板语言的优点: 假设我要生成一个 “hel ...