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;
    }
    
  • 相关阅读:
    (转载)Android content provider基础与使用
    如何解决Android的SDK与ADT不匹配问题
    Android 中断线程的处理
    用AsyncTask 来实现下载图片在android开发中
    开源自己的一个小android项目(美女撕衣服游戏)
    实现在Android开发中的Splash Screen开场屏的效果
    支持在安卓中UI(View)的刷新功能
    android从资源文件中读取文件流显示
    后缀数组 模板题 hdu1403(最长公共(连续)子串)
    Codeforces Round #383 (Div. 1) C(二分图)
  • 原文地址:https://www.cnblogs.com/Friends-A/p/11653412.html
Copyright © 2011-2022 走看看