zoukankan      html  css  js  c++  java
  • Codeforces C. Jzzhu and Cities(dijkstra最短路)

    题目描述:

    Jzzhu and Cities

    time limit per test

    2 seconds

    memory limit per test

    256 megabytes

    input

    standard input

    output

    standard output

    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 m roads connecting the cities. One can go from city (u_i) to (v_i) (and vise versa) using the i-th road, the length of this road is (x_i). 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 s**i (and vise versa), the length of this route is (y_i).

    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 ≤ (10^5); 1 ≤ m ≤ (3·10^5); 1 ≤ k ≤ (10^5)).

    Each of the next m lines contains three integers (u_i), (v_i), (x_i) (1 ≤ (u_i), (v_i) ≤ n; (u_i) ≠ (v_i); (1 ≤ *)(x_i)* ≤ (10^9)).

    Each of the next k lines contains two integers (s_i and y_i (2 ≤ s_i ≤ n; 1 ≤ y_i ≤ 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.

    Examples

    Input

    Copy

    5 5 31 2 12 3 21 3 33 4 41 5 53 54 55 5
    

    Output

    Copy

    2
    

    Input

    Copy

    2 2 31 2 22 1 32 12 22 3
    

    Output

    Copy

    2
    

    思路:

    这道题是要给一个交通网络图,实际上只从1点出发,到其余各个点的最短路径,也就是单源最短路径。然后从1点到某些城市有特殊的边可以直达,路径长度也已知。这些条件给定后,现在1点到各个点的最短路径就实际上已经知道了。现在要删除一些特殊边,只要能保证删除连向某点的特殊边后,从1到这个点的最短距离不发生变化。求最多能删多少条这样的特殊边。

    分析一下,现在已知1到其余点的最短距离,考虑对每一个特殊边,设这条边直连v点,长度为w.

    (1).w>d[v](d为最短路径)的话说明我到v点的最短路径不是通过这条边的,因此这条边可以直接删除。

    (2).若w==d[v],也就是我到v的最短路径可以通过这条边到达,那到底能不能删这条边呢?如果说1就只有一条最短路径到v,也就是到v最短路径只特殊边这一条,那么显然不能删这条边,因为如果删掉1到v的长度会增大。如果1到v最短路径有多条,也就是除了特殊边直达外我还可以通过其它边最短到v,那么这条特殊边就可以删去,而不会影响1到v的最短路径。

    于是需要记录到每个点的最短路径条数。实现的话就要在dijkstra算法进行路径松弛的时候记录分情况下最短路的条数,有些技巧性的更新。

    注意的是最后在遍历特殊边的时候,进行删除到达v的特殊边时要记得实时更新v的最短路径条数。

    代码:

    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <climits>
    #include <queue>
    #define max_n 100005
    #define INF LLONG_MAX
    using namespace std;
    typedef pair<long long,long long> PLL;
    int n,m,k;
    vector<PLL> G[max_n];
    int num = 0;
    long long d[max_n];//最短距离
    long long deg[max_n];//最短路条数
    vector<PLL> train;//特殊边
    //int used[max_n<1];
    /*void dijkstra(int s)
    {
        fill(d,d+max_n,INF);
        fill(used,used+max_n,0);
        d[s] = 0;
        int v;
        while(true)
        {
            int v = -1;
            for(int u = 0;u<n;u++)
            {
                if(!used[u]&&(v==-1)||d[u]<d[v])
                {
                    v = u;
                }
            }
            if(v==-1) break;
            used[v] = 1;
            for(int u = 0;u<n;u++)
            {
                d[u] = min(d[u],d[v]+cost[v][u]);
            }
        }
    }*/
    void dijkstra(int s)
    {
        priority_queue<PLL,vector<PLL>,greater<PLL> > que;
        fill(d,d+max_n,INF);
        d[s] = 0;
        que.push(PLL(0,s));
        while(!que.empty())
        {
            PLL p = que.top();
            que.pop();
            int v = p.second;
            if(d[v]<p.first) continue;
            for(int i = 0;i<G[v].size();i++)
            {
                PLL edge = G[v][i];
                if(d[edge.first]==d[v]+edge.second)//相等最短路数目加一
                {
                    deg[edge.first]++;
                }
                if(d[edge.first]>d[v]+edge.second)//更新则最短路数目刷新为一
                {
                    d[edge.first] = d[v]+edge.second;
                    que.push(PLL(d[edge.first],edge.first));
                    deg[edge.first]=1;
                }
            }
        }
    }
    int main()
    {
        cin >> n >> m >> k;
        for(int i = 0;i<m;i++)
        {
            int u,v;
            long long w;
            cin >> u >> v >> w;
            G[u].push_back(PLL(v,w));
            G[v].push_back(PLL(u,w));
        }
        for(int i = 0;i<k;i++)
        {
            long long to,w;
            cin >> to >> w;
            train.push_back(PLL(to,w));
            G[1].push_back(PLL(to,w));
        }
        dijkstra(1);
        for(int i = 0;i<train.size();i++)
        {
            long long v = train[i].first;
            long long w = train[i].second;
            if(d[v]<w)
            {
                num++;
            }
            if(d[v]==w&&deg[v]>1)
            {
                num++;
                deg[v]--;
            }
        }
        cout << num << endl;
        return 0;
    }
    

    参考文章:

    围巾的ACM,Codeforces 449B Jzzhu and Cities(最短路),https://blog.csdn.net/qq_21057881/article/details/50602265

  • 相关阅读:
    Go语言基础介绍
    webpack教程——css的加载
    Git忽略规则.gitignore梳理
    vue2.0路由-适合刚接触新手简单理解
    JAVA实现DES加密实现详解
    计算机网络: IP地址,子网掩码,网段表示法,默认网关,DNS服务器详解
    Storm:最火的流式处理框架
    神片和神回复
    论C#未来发展
    弄清UTF8和Unicode
  • 原文地址:https://www.cnblogs.com/zhanhonhao/p/11297569.html
Copyright © 2011-2022 走看看