Codeforces 449D:Jzzhu and Cities(最短路,dijkstra)

时间:2019-10-11
本文章向大家介绍Codeforces 449D:Jzzhu and Cities(最短路,dijkstra),主要包括Codeforces 449D: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 ≤ 3\cdot10^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;
}

原文地址:https://www.cnblogs.com/Friends-A/p/11653412.html