Codeforces Round #257 (Div. 2) D. Jzzhu and Cities

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 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
Input
2 2 3
1 2 2
2 1 3
2 1
2 2
2 3
Output
2

  有N个地方,M条线路,K条火车路(从1出发)。最多删掉多少火车路使1到每个点的最短路不变。

  用dijkstra的思路,优先队列每次找出d最小的。先用火车路更新最小的d。当u的最短路确定的时候,若还是那个火车路,没有被别的路更新,说明这条火车路不能删,若这条路已经被更新过,说明火车路能删。

  怎么判断一个点有没有被更新过呢,这里有个巧妙的方法,一开始把节点编号的负值加到优先队列中,如果最后确定最短路的时候还是负值说明没有被更新过。

  有一点要注意,更新条件是d[v]>=d[u]+w,因为如果出现和火车路长度相同的路也要更新,因为这样也可以把火车路删掉。

  把d加入队列的时候可以加d的负值,因为默认的优先队列是先pop大的,负的最大就是正的最小。

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#define INF 0x3f3f3f3f
#define MAXN 200010
#define MAXM 1000010
#define MOD 1000000007
#define MAXNODE 500010
#define sigma_size 28
#define eps 1e-9
using namespace std;
typedef long long LL;
LL N,M,K,d[MAXN],vis[MAXN];
vector<pair<LL,LL> > V[MAXN];
priority_queue<pair<LL,LL> >q;
int main(){
    freopen("in.txt","r",stdin);
    while(cin>>N>>M>>K){
        LL u,v,w;
        for(LL i=1;i<=N;i++) V[i].clear();
        while(!q.empty()) q.pop();
        for(int i=0;i<=N;i++) d[i]=1e18;
        memset(vis,0,sizeof(vis));
        while(M--){
            cin>>u>>v>>w;
            V[u].push_back(make_pair(v,w));
            V[v].push_back(make_pair(u,w));
        }
        while(K--){
            cin>>v>>w;
            d[v]=min(d[v],w);
            q.push(make_pair(-w,-v));
        }
        q.push(make_pair(0,1));
        d[1]=0;
        LL ans=0;
        while(!q.empty()){
            LL u=q.top().second,w=-q.top().first;
            q.pop();
            if(u<0){
                u=-u;
                if(vis[u]) ans++;
            }
            if(vis[u]) continue;
            vis[u]=1;
            LL L=V[u].size();
            for(LL i=0;i<L;i++){
                LL v=V[u][i].first,w=V[u][i].second;
                if(d[v]>=d[u]+w){
                    d[v]=d[u]+w;
                    q.push(make_pair(-d[v],v));
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值