zoukankan      html  css  js  c++  java
  • CF449B最短路

    B. Jzzhu and Cities

    Jzzhu is the president of country A. There are n cities numbered from 1 to n in his country. City 1 is the capital of A. Also there are mroads connecting the cities. One can go from city ui to vi (and vise versa) using the i-th road, the length of this road is xi. Finally, there are k train routes in the country. One can use the i-th train route to go from capital of the country to city si (and vise versa), the length of this route is yi.

    Jzzhu doesn't want to waste the money of the country, so he is going to close some of the train routes. Please tell Jzzhu the maximum number of the train routes which can be closed under the following condition: the length of the shortest path from every city to the capital mustn't change.

    Input

    The first line contains three integers n, m, k (2 ≤ n ≤ 105; 1 ≤ m ≤ 3·105; 1 ≤ k ≤ 105).

    Each of the next m lines contains three integers ui, vi, xi (1 ≤ ui, vi ≤ nui ≠ vi; 1 ≤ xi ≤ 109).

    Each of the next k lines contains two integers si and yi (2 ≤ si ≤ n; 1 ≤ yi ≤ 109).

    It is guaranteed that there is at least one way from every city to the capital. Note, that there can be multiple roads between two cities. Also, there can be multiple routes going to the same city from the capital.

    Output

    Output a single integer representing the maximum number of the train routes which can be closed.

    Sample test(s)
    input
    5 5 3 1 2 1 2 3 2 1 3 3 3 4 4 1 5 5 3 5 4 5 5 5
    output
    2


    题意:有n座城市m条边,现在可以修k条铁路,城市1是首都,如果到第i座城市的最短路比修到这座城市的铁路的距离要长,就修铁路,
    问你有多少条铁路是没必要修的。
    思路:我们可以首先把首都到每座城市的距离用首都到每座城市的铁路距离表示,然后再用dijkstra算法+优先队列跑一次所有最短路,
    看看那条最短路改变了,如果改变了,就标记这个顶点。由于有重边,所以在输入铁路的时候要去重,取最短距离的铁路,其他的重边
    都是没必要修的,由于有的点是没有铁路的,所以要标记那些有铁路的点,好最后计数。


    代码:
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<vector>
    using namespace std;
    //typedef __int64 LL;
    typedef long long LL;
    const int maxn = 100009;
    const int maxm = 300009;
    const LL inf = (LL)1<<40;
    
    struct node
    {
        int v,w;
        node(int v=0,int w=0):v(v),w(w){}
        bool operator < (const node a)const
        {
            return w > a.w;
        }
    };
    
    vector<node> eg[maxn];
    LL dis[maxn];
    int n;
    int vis[maxn];
    int used[maxn];
    
    void DIJ()
    {
        int i;
        memset(used,0,sizeof(used));
        priority_queue<node> pq;
        dis[1] = 0;
        for(i=1;i<=n;i++)
            pq.push(node(i,dis[i]));
        while(!pq.empty())
        {
            int u = pq.top().v;
            int w = pq.top().w;
            pq.pop();
            if(w > dis[u])continue;
            for(int i=0;i<eg[u].size();i++)
            {
                int v = eg[u][i].v;
                 w = eg[u][i].w;
                if(dis[v] > dis[u] + w)
                {
                    dis[v] = dis[u] + w;
                    used[v] = 1;   // 
                    pq.push(node(v,dis[v]));
                }else if(dis[v] == dis[u] + w)
                    used[v] = 1;
            }
            
        }
        
    }
    inline int min(int a,int b){return a < b ? a : b;}
    
    int main()
    {
        int m,k,i,a,b,c;
        while(~scanf("%d%d%d",&n,&m,&k))
        {
            for(i=0;i<=n;i++)
            {
                dis[i] = inf;
                eg[i].clear();
            }
            memset(vis,0,sizeof(vis));
            for(i=0;i<m;i++)
            {
                scanf("%d%d%d",&a,&b,&c);
                eg[a].push_back(node(b,c));
                eg[b].push_back(node(a,c));
            }
            int j = 0;
            int sum = 0;
            for(i=0;i<k;i++)
            {
                scanf("%d%d",&a,&b);
                if(!vis[a])
                {
                    vis[a] = 1;
                    dis[a] = b;
                }else
                {
                    sum ++;
                    dis[a] = min(dis[a],b);
                }
            }
            DIJ();
            for(i=1;i<=n;i++)
                if(vis[i] && used[i]) sum ++;
                printf("%d
    ",sum);
                
        }
        return 0;
    }
    
    /*
    
      
        5 5 3
        1 2 1
        2 3 2
        1 3 3
        3 4 4
        1 5 5
        3 5
        4 5
        5 5
        5 4 3
        1 2 999999999
        2 3 1000000000
        3 4 529529529
        5 1 524524524
        5 524444444
        5 529999999
        2 1000000000
        2 2 3
        1 2 2
        2 1 3
        2 1
        2 2
        2 3
        
          
            
    */
  • 相关阅读:
    【HDU3681】Prison Break-状态压缩DP+BFS+二分答案
    【BashuOJ3520】警察局长-最短路树+树上背包+概率DP
    【POJ1201】Intervals-差分约束系统+单源最长路
    【BashuOJ2041】最大矩形-矩阵型DP
    【BashuOJ2041】最大矩形-矩阵型DP
    deleted
    deleted
    deleted
    deleted
    deleted
  • 原文地址:https://www.cnblogs.com/BruceNoOne/p/3886692.html
Copyright © 2011-2022 走看看