Jzzhu is the president of country A. There are n cities numbered from1 ton in his country. City1 is the capital of A. Also there arem roads connecting the cities. One can go from cityui tovi (and vise versa) using thei-th road, the length of this road isxi. Finally, there arek train routes in the country. One can use thei-th train route to go from capital of the country to citysi (and vise versa), the length of this route isyi.
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 integersui, vi, xi(1 ≤ ui, vi ≤ n; ui ≠ vi; 1 ≤ xi ≤ 109).
Each of the next k lines contains two integerssi andyi(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
还有就是我发现vector的速度,好像还是蛮快的,我用数组模拟邻接表被T了,用vector就过了,所以说以后尽量用vector来写。
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#define INF 1e18
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
/*
这道题,我没能读懂几个地方,我想的是只能走road。rail 只是一种被比较的对象,所以我们只需要算出来road的路径,就好了。
现在我才知道,原来,两者是可以混合使用的,就是说可以先走火车,在中转去别的地方。
题解:先建立铁路,然后再去找最短路径,如果这点的最短路径小于等于这点的火车直达路径,那么这个火车线,就可以删掉
所以讲,这种思维还是自己需要练习的
*/
int n,road,rail;
typedef pair<int,int> pii;
vector<pii> graph[maxn];//存储边和权值
int vis[maxn];
ll dis[maxn];
int mark[maxn];//标记該点是不是有火车直达
int main ()
{
scanf("%d %d %d",&n,&road,&rail);
for(int i=0;i<road;i++)
{
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
graph[u].push_back(make_pair(v,w));
graph[v].push_back(make_pair(u,w));//vise versa 反之亦然,不是等等的意思,也就是说双向边
}
for(int i=0;i<=n;i++)
dis[i]=INF;
dis[1]=0;//自己距离自己是最近的
memset(vis,0,sizeof(vis));
queue<int> q;
q.push(1);
vis[1]=1;
for(int i=0;i<rail;i++)
{
int v,w;
scanf("%d %d",&v,&w);
if(dis[v]>w)//找到铁路最近的
{
dis[v]=w;mark[v]=1;//标记这个地方有铁路
if(!vis[v])
{
vis[v]=1;
q.push(v);//不用担心,后面有更小的铁路怎么办,
//这里面只是放着点,还没有明确距离,所以可以直接看作最近的距离
}
}
}
while(q.size())
{
int now=q.front();
q.pop();
vis[now]=0;
for(int i=0;i<graph[now].size();i++)
{
int v=graph[now][i].first,w=graph[now][i].second;
if(dis[v]>=dis[now]+w&&mark[v])//这个点有直达的铁路,然而我们却可以通过别的点松弛,来得到相同甚至更小的结果
mark[v]=0; //我们就可以删掉这条边
if(dis[v]>dis[now]+w)
{
dis[v]=dis[now]+w;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
for(int i=0;i<=n;i++)
rail-=mark[i];
printf("%d\n",rail);
return 0;
}