zoukankan      html  css  js  c++  java
  • POJ 3463 Sightseeing

     

     

    题意:给你一个图和起始两点,要求求出两点之间最短路和比最短路长一个单位的路径条数总和。

    思路分析:看到长一个单位想到次短路,次短路要用到A*,但是发现估价函数好像不会写(其实是可以的,但蒟蒻不会)。于是我们采取dijkstra算法来解决这道问题,由于要求求出两条路径,于是dis数组开成dis[N][2],分别表示最短路长度和次短路长度,sum数组表示从起点到当前点的路径条数,那么我们更新时就会有以下四种情况: 

     1.若找到比当前最短路更短的路径时,这条路成为最短路,原来最短路成为次短路。

     2.若当前长度和当前最短路长度相等时,sum累加一下。

     3.若当前路长度在最短,次短之间,这条路变为次短路。

     4..若当前长度和当前次短路长度相等时,sum累加一下。

    之后就没有什么了,注意题目说是单向边。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<queue>
     5 using namespace std;
     6 const int N=1e6+10;
     7 struct Node{
     8     int next,to,dis;
     9 }edge[N];
    10 int Head[N],tot;
    11 void Add(int x,int y,int z){
    12     edge[++tot].to=y;
    13     edge[tot].next=Head[x];
    14     edge[tot].dis=z;
    15     Head[x]=tot;
    16 }
    17 int dis[N][2],sum[N][2];
    18 struct Edge{
    19     int num,dis,t;
    20     Edge(int x,int y,int z){
    21         num=x;dis=y;t=z;
    22     }
    23     bool operator < (const Edge& a)const{
    24         return a.dis<dis;
    25     }
    26 };
    27 priority_queue<Edge>q;
    28 int vis[N][2];
    29 void dijkstra(int x){
    30     memset(dis,0x3f,sizeof(dis));
    31     memset(sum,0,sizeof(sum));
    32     memset(vis,0,sizeof(vis));
    33     dis[x][1]=dis[x][0]=0;
    34     sum[x][0]=1;
    35     q.push(Edge(x,0,0));
    36     while(!q.empty()){
    37         Edge top=q.top();q.pop();
    38         if(vis[top.num][top.t]) continue;
    39         vis[top.num][top.t]=1;
    40         int u=top.num,t=top.t;
    41         for(int i=Head[u];i;i=edge[i].next){
    42             int v=edge[i].to;
    43             if(dis[v][0]>dis[u][t]+edge[i].dis){
    44                 dis[v][1]=dis[v][0];sum[v][1]=sum[v][0];
    45                 dis[v][0]=dis[u][t]+edge[i].dis;
    46                 sum[v][0]=sum[u][t];
    47                 q.push(Edge(v,dis[v][0],0));
    48                 q.push(Edge(v,dis[v][1],1));
    49             }
    50             else if(dis[v][0]==dis[u][t]+edge[i].dis){
    51                 sum[v][0]+=sum[u][t];
    52             }
    53             else if(dis[v][1]>dis[u][t]+edge[i].dis){
    54                 dis[v][1]=dis[u][t]+edge[i].dis;
    55                 sum[v][1]=sum[u][t];
    56                 q.push(Edge(v,dis[v][1],1));
    57             }
    58             else if(dis[v][1]==dis[u][t]+edge[i].dis){
    59                 sum[v][1]+=sum[u][t];
    60             }
    61         } 
    62     }
    63 }
    64 int main(){
    65     //freopen("a.txt","r",stdin);
    66     int T;
    67     scanf("%d",&T);
    68     while(T--){
    69         memset(Head,0,sizeof(Head));
    70         memset(edge,0,sizeof(edge));
    71         memset(sum,0,sizeof(sum));
    72         int n,m;
    73         scanf("%d%d",&n,&m);
    74         for(int i=1;i<=m;++i){
    75             int x,y,z;
    76             scanf("%d%d%d",&x,&y,&z);
    77             Add(x,y,z);
    78         }
    79         int x,y;
    80         scanf("%d%d",&x,&y);
    81         dijkstra(x);
    82         int ans=sum[y][0];
    83         if(dis[y][0]+1==dis[y][1]) ans+=sum[y][1];//次短路比最短路长1时累加 
    84         printf("%d
    ",ans);
    85     }
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    关于Windows 2000,IIS 5/4下面,Form内容超过200K解决办法!
    获取客户端网卡MAC地址和IP地址的几种方法
    关于Java的异常捕获
    redis的swap
    Linux下C++程序获取运行时间的一种方式
    CentOS 修改IP地址, DNS, 网关[内容来源网络]
    [转]ubuntu12.04搭建ruby on rails 环境
    rails环境 bundle 时无法安装nokogiri 完美解决
    SQL Server – 冷知识 (新手)
    Typescript – 学习笔记 tsconfig.json
  • 原文地址:https://www.cnblogs.com/li-jia-hao/p/12953592.html
Copyright © 2011-2022 走看看