poj 3463 Sightseeing(次短路+条数统计)

/*
对dij的再一次理解
每个点依旧永久标记
只不过这里多搞一维
0 1 表示最短路还是次短路
然后更新次数相当于原来的两倍
更新的时候搞一下就好了
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#define maxn 1010
using namespace std;
int T,n,m,num,head[maxn],dis[maxn][2],f[maxn][2],c[maxn][2];
struct edge{
    int v,t,pre;
}e[maxn*10];
struct node{
    int k,r,t;
    bool operator < (const node &x) const{
        return t>x.t;
    }
};
priority_queue<node>q;
int init(){
    int x=0,f=1;char s=getchar();
    while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    return x*f;
}
void Clear(){
    for(int i=1;i<=n;i++)
        head[i]=0;
    num=0;
    while(!q.empty())q.pop();
}
void Add(int from,int to,int dis){
    num++;e[num].v=to;
    e[num].t=dis;
    e[num].pre=head[from];
    head[from]=num;
}
void Dij(int u,int v){
    memset(dis,127/3,sizeof(dis));
    memset(f,0,sizeof(f));
    memset(c,0,sizeof(c));
    c[u][0]=1;
    dis[u][0]=0;
    q.push((node){u,0,0});
    while(!q.empty()){
        int k=q.top().k;int r=q.top().r;
        q.pop();if(f[k][r])continue;
        f[k][r]=1;
        for(int i=head[k];i;i=e[i].pre){
            int v=e[i].v;
            if(dis[v][0]>dis[k][r]+e[i].t){
                dis[v][1]=dis[v][0];
                c[v][1]=c[v][0];
                dis[v][0]=dis[k][r]+e[i].t;
                c[v][0]=c[k][r];
                q.push((node){v,0,dis[v][0]});
                q.push((node){v,1,dis[v][1]});
            }
            else if(dis[v][0]==dis[k][r]+e[i].t){
                c[v][0]+=c[k][r];
                q.push((node){v,0,dis[v][0]});
            }
            else if(dis[v][1]>dis[k][r]+e[i].t){
                dis[v][1]=dis[k][r]+e[i].t;
                c[v][1]=c[k][r];
                q.push((node){v,1,dis[v][1]});
            }
            else if(dis[v][1]==dis[k][r]+e[i].t){
                c[v][1]+=c[k][r];
                q.push((node){v,1,dis[v][1]});
            }
        }
    }
    int ans=c[v][0];
    if(dis[v][1]==dis[v][0]+1)ans+=c[v][1];
    printf("%d\n",ans);
}
int main()
{
    T=init();
    while(T--){
        n=init();m=init();
        int u,v,t;Clear();
        for(int i=1;i<=m;i++){
            u=init();v=init();t=init();
            Add(u,v,t);
        }
        u=init();v=init();
        Dij(u,v);
    }
    return 0;
}
时间: 2024-09-30 07:26:10

poj 3463 Sightseeing(次短路+条数统计)的相关文章

poj 3463 Sightseeing——次短路计数

题目:http://poj.org/problem?id=3463 当然要给一个点记最短路和次短路的长度和方案. 但往优先队列里放的结构体和vis竟然也要区分0/1,就像把一个点拆成两个点了一样. 不要区分k的fx. #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=1005,M=10005; int T

poj 3463 Sightseeing(最短路+次短路)

http://poj.org/problem?id=3463 大致题意:给出一个有向图,从起点到终点求出最短路和次短路的条数之和. 解法: 用到的数组:dis[i][0]:i到起点的最短路,dis[i][1]:i到起点的严格次短路 vis[i][0],vis[i][1]:同一维的vis数组,标记距离是否已确定 sum[i][0]:i到起点的最短路条数,sum[i][1]:i到起点的次短路条数 同一维dijkstra,内循环先找出最短的距离(次短路或最短路)d,然后枚举与该点相连的点: if(d

poj 3463 Sightseeing (dij 求最短路和次短路并计数)

dijkstra求最短路和次短路的求法和计算  模板 dijkstra求最短路的变形. 外循环要循环2*n-1次,因为dis[n][2]有2*n个状态,而dis[s][0]已经用过一次. 算法: 1.如果比最短路短就更新最短路和次短路. 2.如果和最短路相等,更新最短路的计数. 3.如果和次短路相等,更新次短路的方法数. 4.如果比次短路短,更新次短路. #include<cstdio> #include<iostream> #include<cstring> #inc

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

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

POJ 3463 Sightseeing (最短路 次短路)

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. On this way, the tourists in the bus can see the sights alongside the route travelled. Moreover, the bus mak

(最短路深入)POJ 3463 - Sightseeing

题意: 给一个有向图,计算最短路和比最短路少1的路的条数的和. 分析: 这题真的写死我了. 因为之前很少接触最短路问题,所谓偶尔遇到一次也是套的模板,根本没有细细思考过dijsktra算法.所以栽在了这题上. 这题就是求最短路和次短路. 核心思想在于修改最短路松弛的条件,并且每个节点同时维护最短路和次短路. 很多博主写的很详细,我也不多说了,只是写个博文记录一下自己有多渣,在学习算法的道路上自己真的思考的不够多,也不够努力. 代码: 1 #include <set> 2 #include &l

poj 3463 Sightseeing 最短路径数量

题意: 求有向图中最短路和比最短路大1的路径数量. 思路: 需要理解dijkstra算法中dis[n]数组的含义,设cnt[i]表示到点i的最短路径数量,cnt1[i]表示到点i比最短路大1的路径数量.在运行dijkstra算法的过程中每次获得最小dis[i]的时候可以对所有dis[v]+w(v,i)==dis[i]的v做如下更新cnt[i]+=cnt[v],cnt1[i]+=cnt1[v].而当所有值为某数的dis[i]计算完成时也就是对任意i,dis[i]为同一值且不再变化时,可以对这些满足