文章标题 CoderForces 450D : Jzzhu and Cities(最短路---spfa)
2016-11-27 17:53
417 查看
Jzzhu and Cities
DescriptionJzzhu 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 ≤ 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
Output a single integer representing the maximum number of the train routes which can be closed.
Sample Input
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到点v,现在要节省金钱拆掉一些铁路,在不影响每个点与点1之间的最短路的情况下,问能拆掉的铁路的最大值。
分析:先求一次最短路,然后铁路的权值与对应的点的最短路的权值比较,如果铁路的比较大,说明可以删掉;否则将将该边加入到图中,再计算一次最短路,并记录每个点的前一个点(即前驱),然后枚举铁路,已经删除的铁路就不用考虑了,如果铁路的权值比最短路的权值大,说明该铁路可以删除,如果权值相等,看这个点的前驱,如果不是1,说明可以从其他点到达,这条铁路也可以删除。
代码:
#include<iostream> #include<string> #include<cstdio> #include<cstring> #include<vector> #include<math.h> #include<map> #include<queue> #include<algorithm> using namespace std; const int inf = 0x3f3f3f3f; const long long INF = 0x3f3f3f3f3f3f3f3f; const int maxn = 105000; typedef pair<int,int> pii; int n,m,k; struct edge{ //边的结构体 int v; long long w; edge(int _v,long long _w){ v=_v; w=_w; } edge(){} }; vector <edge> G[maxn]; //用向量存储图 struct Train{ int s; long long y; }; Train train[maxn]; long long dis[maxn]; //源点到各个点的最短路 int vis[maxn]; //标记是否在队列中 queue <int> q; int pre[maxn];//每个点的前驱 int had_cut[maxn]; //标记已经被砍掉的铁路 void spfa(){ while (!q.empty()) q.pop(); //清除队列 memset(vis,0,sizeof (vis)); for (int i=0;i<maxn;i++) dis[i]=INF; //初始化每个点的最短路为无穷大 dis[1]=0; q.push(1); vis[1]=1; while (!q.empty()){ int u=q.front();q.pop();vis[u]=0; for (int i=0;i<G[u].size();i++){ int v=G[u][i].v; long long w=G[u][i].w; if (dis[v]>dis[u]+w){ //如果有更短的路,则松弛 dis[v]=dis[u]+w; if (!vis[v]){ //如果没有在队列中则加入队列 q.push(v); vis[v]=1; } } } } } void spfa2(){ while (!q.empty()){ int u=q.front();q.pop();vis[u]=0; for (int i=0;i<G[u].size();i++){ int v=G[u][i].v; long long w=G[u][i].w; if (dis[v]>dis[u]+w){ dis[v]=dis[u]+w; pre[v]=u; //记录前驱 if (!vis[v]){ q.push(v); vis[v]=1; } } else if(dis[v]==dis[u]+w&&pre[v]<u){ pre[v]=u; //记录前驱 } } } } int main () { while (scanf ("%d%d%d",&n,&m,&k)!=EOF){ for (int i=0;i<maxn;i++)G[i].clear(); //清空向量 memset (pre,-1,sizeof (pre)); memset (had_cut,0,sizeof (had_cut)); int u,v,x; for(int i=0;i<m;i++){ scanf ("%d%d%lld",&u,&v,&x); G[u].push_back(edge(v,x)); //加边,无向的 G[v].push_back(edge(u,x)); } for (int i=0;i<k;i++){ scanf ("%d%lld",&train[i].s,&train[i].y); } spfa(); //第一次求最短路 int cnt=0; for (int i=0;i<k;i++){ int v=train[i].s; long long w=train[i].y; if (dis[v]<=w){ //找权值比最短路大的 had_cut[i]=1; //标记已经删除 cnt++; } else { G[1].push_back(edge(v,w)); //如果没有就加入图中 G[v].push_back(edge(1,w)); pre[v]=1; dis[v]=w; q.push(v); vis[v]=1; //标记 } } spfa2(); //第二次最短路 for (int i=0;i<k;i++){ if (had_cut[i])continue; //已经删除的就直接跳过 int v=train[i].s; long long w=train[i].y; if ((dis[v]==w&&pre[v]!=1)||(dis[v]<w)){ //如果权值大的或者权值相等但其前驱不是1则说明可以删除 cnt++; } } printf ("%d\n",cnt); //输出答案 } return 0; }
相关文章推荐
- B - Jzzhu and Cities CodeForces - 450D spfa||dijkstra+堆优化
- 文章标题 coderforces 514D : R2D2 and Droid Army (二分+RMQ预处理)
- 文章标题 coderforces 755C : PolandBall and Forest(并查集)
- 文章标题 coderforces 339D : Xenia and Bit Operations (线段树+点修改)
- Jzzhu and Cities CodeForces - 449B (最短路 + 最短路的条数)
- 文章标题 CoderForces 755A : PolandBall and Hypothesis(水)
- 文章标题 Coderforces 755B : PolandBall and Game(水)
- CF 449B - Jzzhu and Cities(最短路)
- 文章标题 Coderforces 908C New Year and Curling(暴力)
- Codeforces Round #257(Div.2) D Jzzhu and Cities --SPFA
- 文章标题 coderforces 761B : Dasha and friends(KMP)
- 文章标题 coderforces 761C : Dasha and Password(贪心+暴力)
- Jzzhu and Cities( cf450D) 最短路
- 文章标题 coderforces 148D : Bag of mice (概率DP)
- Codeforces 450D - Jzzhu and Cities(最短路)
- Jzzhu and Cities CodeForces - 450D
- D Jzzhu and Cities --SPFA
- codeforces499B————Jzzhu and Cities(最短路)
- 文章标题 Coderforces 343D : Water Tree(dfs序+线段树)
- 文章标题 coderforces 609E : Minimum spanning tree for each edge (MST+LCA)