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[55];
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[55][2];
int dp[55][2];
bool vis[55][2];
//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=0;i<n;i++)
    {
        dist[i][0]=dist[i][1]=INF;
    }
    memset(dp,0,sizeof(dp));
    memset(vis,false,sizeof(vis));
    priority_queue<node> Q;
    node p,q;
    dist[start][0]=0;
    dp[start][0]=1;
    p.dist=0,p.mark=0,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=0;i<g[p.v].size();i++)
        {
            int v=g[p.v][i].v;
            int w=g[p.v][i].w;
            if(!vis[v][0] && p.dist+w <dist[v][0])
            {
                //可能为次短路
                if(dist[v][0]!=INF)
                {
                    q.v=v,q.dist=dist[v][1],q.mark=1;
                    dist[v][1]=dist[v][0];
                    dp[v][1]=dp[v][0];
                    Q.push(q);
                }
                dist[v][0]=p.dist+w;
                dp[v][0]=dp[p.v][p.mark];
                q.v=v,q.dist=dist[v][0],q.mark=0;
                Q.push(q);
            }
            else if(!vis[v][0] && p.dist+w==dist[v][0])
            {
                dp[v][0]+=dp[p.v][p.mark];
            }
            else if(!vis[v][1] && p.dist+w<dist[v][1])
            {
                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(!vis[v][1]&&p.dist+w==dist[v][1])
            {
                dp[v][1]+=dp[p.v][p.mark];
            }
        }
    }
}

int main(){
    while(~scanf("%d%d%d%d",&n,&m,&s,&e))
    {
        for(int i=0;i<n;i++)g[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;
            g[u].push_back(p);
        }
        dijkstra(s,e);
        printf("%d %d\n",dist[e][1],dp[e][1]);
    }
    return 0;
}
时间: 2024-10-25 00:21:12

HDU 3191 次短路长度和条数的相关文章

POJ 3255 &amp;&amp; HDU 1688 &amp;&amp; HDU 3191 次短路问题

POJ 3255 Roadblocks Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7627   Accepted: 2798 Description Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best friends. She does not want to get to her old h

HDU1688 Sightseeing(SPFA 求最短路与次短路的路径条数)可用作模板

Sightseeing Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 718    Accepted Submission(s): 293 Problem Description Tour operator Your Personal Holiday organises guided bus trips across the Bene

POJ_3463_Sightseeing(最短路/次短路条数)

Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7421   Accepted: 2659 Description Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the bus moves from one city S to another city F. O

hdu 1688 Sightseeing【最短路,次短路条数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题意:求最短路和次短路条数如果次短路长度=最短路长度+1 这输出次短路条数+最短路条数,否则输出最短路条数 分析:这是到模版题,献上模版: #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> #include<

HDU 1688 Sightseeing 【输出最短路+次短路条数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题目大意:给n个点,m条有向边.再给出起点s, 终点t.求出s到t的最短路条数+次短路条数. 思路: 1.最短路和次短路是紧密相连的,在最短路松弛操作中,当我们找到一条更短的路径,也就意味着之前的路径不再是最短路,而成为了次短路,利用这个关系可以实现状态的转移. 2.好久没写优先队列了,都忘记了加个 priority_queue, 这样才能写重载,才能排序. 注释在代码里: 1 #includ

HDU 3191How Many Paths Are There(TOPE排序 求次短路及条数)

How Many Paths Are There Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1266    Accepted Submission(s): 437 Problem Description oooccc1 is a Software Engineer who has to ride to the work place

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/Others)Total Submission(s): 1010    Accepted Submission(s): 332 Problem Description oooccc1 is a Software Engineer who has to ride to the work place

eoj1818 dijkstra求最短路及其条数

求出有n(1 < n <= 100)个结点有向图中,结点1到结点n的最短路径,以及最短路径的条数. Input 第一行有2个整数n和m( 0 < m < 3000),接下来m行每行有三个整数u,v,w结点u到v之间有一条权为w的边(w<100000). Output 输出只有一行,为结点1到结点n之间的最短路径及其条数(用空格隔开),如果1到n之间不存在路径,输出 -1 0. Sample Input 3 3 1 2 10 2 3 15 1 3 25 Sample Outpu

PKU 3613 Cow Relays (指定路径条数的最短路)

题意:N,T,S,E:给你T条边,每条边两端都有编号和权值,问从S走到E允许走N条边,求最短路. foyld加矩阵快速幂思想. 注意要把边离散 #include <iostream> #include <fstream> #include <string.h> #include <algorithm> using namespace std; #define M 303 #define inf 0x3fffffff struct node { int a[M