zoukankan      html  css  js  c++  java
  • Codeforces 450D:Jzzhu and Cities(最短路,dijkstra)

    D. 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 ≤ 3cdot10^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 ≤ 10^9)).

    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

    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
    

    input

    2 2 3
    1 2 2
    2 1 3
    2 1
    2 2
    2 3
    

    output

    2
    

    题意

    一个城市中有 (m) 条公路和 (k) 条铁路,每条铁路都和起点相连。现在要求在不改变起点到各点最短路径长度的情况下,拆除一些铁路,问最多可以拆除多少条铁路

    思路

    将公路和铁路放在一起建图,然后去跑最短路,在跑最短路的过程中记录一下每个点的入度(该点被多少条最短路径包含)

    铁路可以删除的条件:

    1. 如果起点到该点的最短路径和起点到该点的铁路长度相等,判断该点的入读是否大于 (1),如果大于 (1),这条铁路也是可以删除的(能够到达该点的最短路径不止一条)
    2. 起点到该点的最短路径小于起点到该点的铁路的长度

    代码

    #include <bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    #define ms(a,b) memset(a,b,sizeof(a))
    const int inf=0x3f3f3f3f;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int maxn=1e6+10;
    const int mod=1e9+7;
    const int maxm=1e3+10;
    using namespace std;
    struct edge
    {
        int to,Next;
        ll value;
    }Edge[maxn];
    int head[maxn];
    int tot;
    inline void add_edge(int u,int v,ll w)
    {
        Edge[tot].to=v;
        Edge[tot].Next=head[u];
        Edge[tot].value=w;
        head[u]=tot++;
    }
    struct node
    {
        int u;
        ll d;
        bool operator < (const node & dui) const{return d>dui.d;}
    };
    int ss[maxn];
    ll yy[maxn];
    ll dis[maxn];
    int in[maxn];
    inline void dijkstra(int s)
    {
        priority_queue<node>que;
        que.push(node{s,0});
        dis[s]=0;
        while(!que.empty())
        {
            node res=que.top();
            que.pop();
            int u=res.u;ll d=res.d;
            if(d!=dis[u])
                continue;
            for(int i=head[u];~i;i=Edge[i].Next)
            {
                int v=Edge[i].to;
                ll w=Edge[i].value;
                if(dis[v]==dis[u]+w)
                    in[v]++;
                if(dis[v]>dis[u]+w)
                    in[v]=1,dis[v]=dis[u]+w,que.push(node{v,dis[v]});
            }
        }
    }
    int main(int argc, char const *argv[])
    {
        #ifndef ONLINE_JUDGE
            freopen("/home/wzy/in", "r", stdin);
            freopen("/home/wzy/out", "w", stdout);
            srand((unsigned int)time(NULL));
        #endif
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,m,k;
        cin>>n>>m>>k;
        for(int i=0;i<=n;i++)
            dis[i]=INF;
        ms(head,-1);
        int x,y;
        ll z;
        while(m--)
            cin>>x>>y>>z,add_edge(x,y,z),add_edge(y,x,z);
        for(int i=0;i<k;i++)
            cin>>ss[i]>>yy[i],add_edge(1,ss[i],yy[i]),add_edge(ss[i],1,yy[i]);
        dijkstra(1);
        ll ans=0;
        for(int i=0;i<k;i++)
        {
            if(yy[i]==dis[ss[i]]&&in[ss[i]]>1)
                ans++,in[ss[i]]--;
            if(yy[i]>dis[ss[i]])
                ans++;
        }
        cout<<ans<<endl;
        #ifndef ONLINE_JUDGE
            cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s."<<endl;
        #endif
        return 0;
    }
    
  • 相关阅读:
    PhotoshopCS6中文版图像处理实战从入门到精通
    Web安全开发指南
    OpenStack运维指南
    Word/Excel/PPT 2016高效办公实战从入门到精通
    UG NX 8.5中文版基础教程
    Moldflow 2018模流分析从入门到精通:升级版
    数据库与数据处理:Access 2010实现
    iOS开发网络数据之AFNetworking使用1
    AFNetworking2.5使用2
    iOS项目的完整重命名方法图文教程
  • 原文地址:https://www.cnblogs.com/Friends-A/p/11653412.html
Copyright © 2011-2022 走看看