CodeForces - 449B Jzzhu and Cities


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.

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 integersui, vi, xi(1 ≤ ui, vi ≤ nui ≠ 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

Output a single integer representing the maximum number of the train routes which can be closed.

Example
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
还有就是我发现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;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值