zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    【流量劫持】SSLStrip 终极版 —— location 瞒天过海
    【流量劫持】沉默中的狂怒 —— Cookie 大喷发
    【流量劫持】SSLStrip 的未来 —— HTTPS 前端劫持
    Web 前端攻防(2014版)
    流量劫持 —— 浮层登录框的隐患
    流量劫持能有多大危害?
    流量劫持是如何产生的?
    XSS 前端防火墙 —— 整装待发
    XSS 前端防火墙 —— 天衣无缝的防护
    XSS 前端防火墙 —— 无懈可击的钩子
  • 原文地址:https://www.cnblogs.com/Xiper/p/4570647.html
Copyright © 2011-2022 走看看