In N cities, there are m roads (two-way) in the middle, and K more railways are provided. The railway goes from 1 to V, and now some railways are to be demolished, when the shortest distance (distance 1) of each vertex remains unchanged
Analysis: Calculate the Shortest Path First. If the weight of the railway is greater than the Shortest Path of the railway, you can delete it. Otherwise, add the edge to the graph and find the shortest path. Record the previous vertex of each vertex, then, the railway is enumerated. If the railway weight is greater than the shortest distance, you can delete the deleted railway. If the weight is equal, if the first vertex of the railway is not 1, then this point can be reached by another road, and this railway can be deleted.
Because there are many sides in this question, a maximum of 8x10 ^ 5 can be found, so the use of the adjacent linked list will time out, it is best to use a vector to store the edge.
Time: 296 MS memory: 30968 KB
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <vector>#include <queue>#define lll __int64using namespace std;#define N 100006struct Edge{ int v; lll w; Edge(int _v,lll _w) { v = _v; w = _w; } Edge(){}};struct Train{ int v; lll w;}T[N];vector<Edge> G[N];lll dis[N];int n,m;int head[N],tot,pre[N];int cut[N],vis[N];queue<int> que;void SPFA(int s){ while(!que.empty()) que.pop(); memset(vis,0,sizeof(vis)); vis[s] = 1; que.push(s); for(int i=0;i<=n;i++) dis[i] = 1000000000000000LL; dis[s] = 0; while(!que.empty()) { int u = que.front(); que.pop(); vis[u] = 0; for(int i=0;i<G[u].size();i++) { int v = G[u][i].v; lll w = G[u][i].w; if(dis[v] > dis[u] + w) { dis[v] = dis[u] + w; if(!vis[v]) { vis[v] = 1; que.push(v); } } } }}void SPFA2(){ while(!que.empty()) { int u = que.front(); que.pop(); vis[u] = 0; for(int i=0;i<G[u].size();i++) { int v = G[u][i].v; lll w = G[u][i].w; if(dis[v] > dis[u] + w) { dis[v] = dis[u] + w; pre[v] = u; if(!vis[v]) { que.push(v); vis[v] = 1; } } else if(dis[v] == dis[u] + w && pre[v] < u) pre[v] = u; } }}int main(){ int i,j,k; int u,v,y; lll w; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { tot = 0; for(i=0;i<=n;i++) G[i].clear(); memset(head,-1,sizeof(head)); memset(cut,0,sizeof(cut)); memset(pre,-1,sizeof(pre)); for(i=0;i<m;i++) { scanf("%d%d%I64d",&u,&v,&w); G[u].push_back(Edge(v,w)); G[v].push_back(Edge(u,w)); } for(i=0;i<k;i++) { scanf("%d%I64d",&y,&w); T[i].v = y; T[i].w = w; } SPFA(1); int cnt = 0; for(i=0;i<k;i++) { int v = T[i].v; lll w = T[i].w; if(dis[v] <= w) { 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; que.push(v); vis[v] = 1; } } SPFA2(); for(i=0;i<k;i++) { if(cut[i]) continue; int v = T[i].v; lll w = T[i].w; if((dis[v] == w && pre[v] != 1) || dis[v] < w) cnt++; } printf("%d\n",cnt); } return 0;}View code