• UESTC_秋实大哥带我飞 2015 UESTC Training for Graph Theory<Problem B>


    B - 秋实大哥带我飞

    Time Limit: 300/100MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
     

    Qiushidage Bring Me Fly

    然而题目和题面并没有什么关系。

    给出n个点,m条带权无向边,问你从1号点到n号点的最短路中有多少种走法?

    Input

    第一行两个数n,m分别表示点的个数和边的个数。 (2n20001m2000

    接下来m行,每行3个数u,v,w表示u号点到v号点有一条距离为w的边。(1u,vn0w100000

    数据保证1号点能够到达n号点,点和边都可以被走多次。

    Output

    如果有无穷种走法,输出-1。否则输出走法的方案数mod 1000000009

    Sample input and output

    Sample InputSample Output
    4 4
    1 2 1
    1 3 1
    2 4 1
    3 4 1
    2
    4 4
    1 2 1
    1 3 1
    2 4 1
    3 4 0
    -1

    解题思路:

    首先我们可以很容易得出:如果通往终点的最短路径上存在 0 边的话,那么肯定是有无穷多种走法的.

     那么我们就设到达终点的状态有两种:

    1. 在通往终点的路上经过 过 0 边
    2. 在通往终点的路上没有经过 过 0 边.

    这样,我们第一遍先跑一次spfa,得出两种状态的最小时间分别为t1,t2.

    如果t2 < t1 ,那么路径肯定是有限条的,我们这时候再跑一次dijkstra求最短路数量即可.

    那么如果t2 >= t1呢,那么最短路径上肯定存在 0 边,即显然有无穷种走法.

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <vector>
    #include <set>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int maxn = 2e3 + 50;
    const int mod = 1000000009;
    const int inf = 1 << 29;
    typedef struct Edge
    {
     int v,w;
     Edge(int v,int w)
      {
           this->v = v ,this->w = w;
      }    
    };
    
    vector<Edge>E[maxn];
    
    int n,m,ans = 1,mincost[maxn][2];
    bool inqueue[maxn][2];
    
    
    typedef struct updatastatus
    {
      int pos;
      int passzero;
      updatastatus(int pos,int passzero)
       {
          this->pos = pos , this->passzero = passzero ;
       }    
    };
    
    queue<updatastatus>q;
    
    void spfa()
    {
       q.push(updatastatus(1,0));
       mincost[1][0] = 0;
       mincost[1][1] = 1 << 28;
       while(!q.empty())
        {
           int pos = q.front().pos , zero = q.front().passzero;q.pop();
           for(int i = 0 ; i < E[pos].size() ; ++ i)
            {
                int nextnode = E[pos][i].v;
                int newcost = mincost[pos][zero] + E[pos][i].w;
                if (zero || !E[pos][i].w)
                 {
                     if (mincost[nextnode][1] == -1 || mincost[nextnode][1] > newcost)
                      {
                          mincost[nextnode][1] = newcost;
                          if (!inqueue[nextnode][1])
                           {
                             q.push(updatastatus(nextnode,1));
                             inqueue[nextnode][1] = false;
                         }
                     }
                 }
                else
                 {
                     if (mincost[nextnode][0] == -1 || mincost[nextnode][0] > newcost)
                       {
                         mincost[nextnode][0] = newcost;
                        if (!inqueue[nextnode][0])
                           {
                             q.push(updatastatus(nextnode,0));
                             inqueue[nextnode][0] = false;
                         }
                      }
                 }
            }
        }
    }
    
    typedef struct tnode
    {
      int u,d;
      friend bool operator < (const tnode & x,const tnode & y)
       {
          return x.d > y.d;    
       }    
      tnode(int u,int d)
       {
             this->u = u , this->d = d;
       }
    };
    
    int times[maxn];
    priority_queue<tnode>dq;
    
    void dijkstra()
    {
       bool vis[maxn];
       int  dis[maxn];
       memset(vis,false,sizeof(vis));
       for(int i = 1 ; i <= n ; ++ i) dis[i] = inf;
       dis[1] = 0;
       times[1] = 1;
       dq.push(tnode(1,0));
       while(!dq.empty())
        {
           int u = dq.top().u , d = dq.top().d;dq.pop();
           if (vis[u]) continue;
           vis[u] = true;
           for(int i = 0 ; i < E[u].size() ; ++ i)
            {
                int nextnode = E[u][i].v;
                int newcost = E[u][i].w;
                if (dis[nextnode] > dis[u] + newcost)
                 {
                     dis[nextnode] = dis[u] + newcost;
                     times[nextnode] = times[u];
                     times[nextnode] %= mod;
                     dq.push(tnode(nextnode,dis[nextnode]));
                 }
                else if(dis[nextnode] == dis[u] + newcost)
                 {
                     times[nextnode] = (times[nextnode] + times[u]) % mod;
                 }
            }
        }
    }
    
    
    int main(int argc,char *argv[])
    {
      scanf("%d%d",&n,&m);
      for(int i = 0 ; i < m ; ++ i)
       {
             int u,v,w;
             scanf("%d%d%d",&u,&v,&w);
             E[u].pb(Edge(v,w));
             E[v].pb(Edge(u,w));
       }
      memset(mincost,-1,sizeof(mincost));
      memset(inqueue,false,sizeof(inqueue));
      memset(times,0,sizeof(times));
      spfa();
      if (mincost[n][1] <= mincost[n][0] && mincost[n][1] != -1)
       printf("-1
    ");
      else if (mincost[n][0] != -1)
       {
            dijkstra();
            printf("%d
    ",times[n] % mod);
       }
      else
       printf("-1
    ");
      return 0;
    }
  • 相关阅读:
    学习Vue.js
    Xmind思维导图
    Webpack 入门教程
    Vscode 使用介绍
    jdk,jre下载安装
    Java JDK下载
    FileZilla FTP下载
    notepad++下载
    windows环境搭建Vue开发环境
    SecureCRTPortable的安装和使用(图文详解)
  • 原文地址:https://www.cnblogs.com/Xiper/p/4570647.html
Copyright © 2020-2023  润新知