• POJ 3463 有向图求次短路的长度及其方法数


    题目大意:

    希望求出走出最短路的方法总数,如果次短路只比最短路小1,那也是可取的

    输出总的方法数

    这里n个点,每个点有最短和次短两种长度

    这里采取的是dijkstra的思想,相当于我们可以不断找到更新到的最短长度来更新其他长度,保证之前的所有可取的最短长度都已经更新的情况下,这样是除了第一个点的最短路为0已知,还需要更新2*n-1次,如果从一个点的位置出发更新了其他点,那么这个位置就不再作为可更新点~~这里都是暴力找最优的可更新的点~~不知道如何做到像普通的dijkstra那种log级别的找点~~

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 #define N 1005
     7 #define M 10005
     8 #define clr(a,b) memset(a,b,sizeof(a))
     9 struct Edge{
    10     int x,y,d,next;
    11     Edge(int x=0,int y=0,int d=0,int next=0):x(x),y(y),d(d),next(next){}
    12 }e[M<<1];
    13 int first[N] , tot , n , m , s , t;
    14 void add_edge(int x,int y,int d)
    15 {
    16     e[tot] = Edge(x,y,d,first[x]);
    17     first[x] = tot++;
    18 }
    19 int dis[N][2] , cnt[N][2] , vis[N][2];
    20 void dijkstra(int s , int t)
    21 {
    22     clr(dis,0x3f);clr(vis,0);clr(cnt,0);
    23     dis[s][0]=0;cnt[s][0]=1;
    24     for(int i=1;i<2*n;i++){
    25         int a=0 , b=0 , curd=0x7fffffff;
    26         for(int j=1;j<=n;j++){
    27             if(dis[j][0]<curd && !vis[j][0]) curd=dis[j][0] , a=j,b=0;
    28             if(dis[j][1]<curd && !vis[j][1]) curd=dis[j][1] , a=j,b=1;
    29         }
    30        // cout<<a<<" "<<b<<" "<<curd<<endl;
    31         vis[a][b]=1;
    32         for(int i=first[a];~i;i=e[i].next){
    33             int v = e[i].y , nowd=curd+e[i].d;
    34             if(nowd<dis[v][0]){
    35                 dis[v][1]=dis[v][0];cnt[v][1]=cnt[v][0];
    36                 dis[v][0]=nowd;cnt[v][0]=cnt[a][b];
    37             }
    38             else if(nowd == dis[v][0]){
    39                 cnt[v][0]+=cnt[a][b];
    40             }
    41             else if(nowd <dis[v][1]){
    42                 dis[v][1]=nowd ;cnt[v][1]=cnt[a][b];
    43             }
    44             else if(nowd==dis[v][1]){
    45                 cnt[v][1]+=cnt[a][b];
    46             }
    47         }
    48     }
    49   //  cout<<cnt[t][0]<<" "<<cnt[t][1]<<endl;
    50     if(dis[t][1]-1 == dis[t][0]) cnt[t][0]+=cnt[t][1];
    51     printf("%d
    " , cnt[t][0]);
    52 }
    53 int main()
    54 {
    55    // freopen("a.in" , "r" , stdin);
    56     int T;
    57     scanf("%d" , &T);
    58     while(T--){
    59         scanf("%d%d" , &n , &m);
    60         clr(first,-1);tot=0;
    61         for(int i=0; i<m ; i++){
    62             int x,y,d;
    63             scanf("%d%d%d" , &x,  &y , &d);
    64             add_edge(x , y , d);
    65         }
    66 
    67         scanf("%d%d" , &s , &t);
    68         dijkstra(s,t);
    69     }
    70 
    71     return 0;
    72 }
  • 相关阅读:
    Knight Moves
    Knight Moves
    Catch him
    Catch him
    Linux查看硬件信息以及驱动设备的命令
    23种设计模式彩图
    Android开发指南-框架主题-安全和许可
    Android启动组件的三种主流及若干非主流方式
    ACE在Linux下编译安装
    void及void指针含义的深刻解析
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/5330822.html
Copyright © 2020-2023  润新知