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.
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 ≤ n; ui ≠ 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 a single integer representing the maximum number of the train routes which can be closed.
5 5 3 1 2 1 2 3 2 1 3 3 3 4 4 1 5 5 3 5 4 5 5 5
2
2 2 3 1 2 2 2 1 3 2 1 2 2 2 3
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;
}