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. 说说JSON和JSONP,也许你会豁然开朗,含jQuery使用jsonp用例

    [原创]说说JSON和JSONP,也许你会豁然开朗,含jQuery用例  前言: 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了 ...

  2. VS与SQL资源

    经常在网上看到有同学费尽心思的找SQL server数据库各版本的下载地址,看到别人的求助贴就不自觉的想去帮助他们,但是一个一个去帮助又不太现实,毕竟个人精力有限,既然大家有需求,那么笔者就本着乐于分 ...

  3. C# WinForm开发系列 - 文章索引

    该系列主要整理收集在使用C#开发WinForm应用文章及相关代码, 平时看到大家主要使用C#来开发Asp.Net应用,这方面的文章也特别多,而关于WinForm的文章相对少很多,而自己对WinForm ...

  4. struts2 标签变形和 样式class无效 问题解决方法

    在jsp使用Struts2标签的时候会发现,出现严重变形问题. <s:textfield type="text" name="username" labe ...

  5. JS遍历Table的所有单元格内容

    用JS去遍历Table的所有单元格中的内容,可以用如下JS代码实现: 这个方法的参数是唯一标识Table的id,用document对象的获取. function GetInfoFromTable(ta ...

  6. emergency monitoring和real-time ADDM

    emergency monitoring面临的挑战: 1.sick systems 2.slow database -所有用户查询响应慢 -性能界面刷新数据慢 -吞吐量严重降低 3.因为内部资源竞争数 ...

  7. mysql - tmp_table_size & max_heap_table_size

    Command-Line Format --tmp_table_size=# System Variable Name tmp_table_size Variable Scope Global, Se ...

  8. systemd自启动java程序

    一.背景条件 1. Linux系统是Debian 8 2. Java程序是test.jar,安装路径是/home/test/test.jar 二.编写java的启动脚本 startTest.sh #! ...

  9. 如何通过sql的insert语句插入大量字符串到oracle的clob字段?

    当通过insert语句直接插入大量字符串(主要是html的内容),超过4000字符时候,就会报: ORA-01489: 字符串连接的结果过长 虽然字段是clob,足以存储,但是通过这种直接插入的时候, ...

  10. [转]Java中使用Runtime和Process类运行外部程序

    帖子1: 使用Runtime.getRuntime().exec()方法可以在java程序里运行外部程序.  1. exec(String command)  2. exec(String comma ...