题目链接:http://codeforces.com/problemset/problem/449/B
分析:先把路和铁路都塞图里跑一遍优先队列的dijkstra(存图的时候要考虑重边,路无所谓,但是铁路需要只取最短并直接把答案加一次,也就是直接删掉这条铁路);
在进行dijikstra时储存到该节点路径为最短路的入度;
如果铁路长度大于最短路就直接删除,如果等于最短路就看该点路径为最短路的入度是否大于1,如果大于就可以删除该铁路
1 #include<iostream> 2 #include<sstream> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<string> 6 #include<cstring> 7 #include<algorithm> 8 #include<functional> 9 #include<iomanip> 10 #include<numeric> 11 #include<cmath> 12 #include<queue> 13 #include<vector> 14 #include<set> 15 #include<cctype> 16 const double PI = acos(-1.0); 17 const int INF = 0x3f3f3f3f; 18 const int NINF = -INF - 1; 19 const int maxn = 3e5 + 5; 20 typedef long long ll; 21 #define MOD 1000000007 22 using namespace std; 23 typedef pair<ll, int> P; 24 struct edge{ 25 int to; 26 ll cost; 27 }; 28 int n, m, k; 29 vector<edge> G[maxn]; 30 ll d[maxn]; 31 ll in[maxn], tmp[maxn]; 32 void dijkstra(int s) 33 { 34 priority_queue<P, vector<P>, greater<P>> q; 35 for (int i = 0; i <= n; ++i) 36 d[i] = INF; 37 d[s] = 0; 38 q.push(P(0, s)); 39 while (q.size()) 40 { 41 P p = q.top(); 42 q.pop(); 43 int v = p.second; 44 if (d[v] != p.first) continue; 45 for (int i = 0; i < G[v].size(); ++i) 46 { 47 edge e = G[v][i]; 48 if (d[e.to] > d[v] + e.cost) 49 { 50 d[e.to] = d[v] + e.cost; 51 in[e.to] = 1; 52 q.push(P(d[e.to], e.to)); 53 } 54 else if (d[e.to] == d[v] + e.cost) in[e.to]++; 55 } 56 } 57 } 58 int main() 59 { 60 std::ios::sync_with_stdio(false); 61 int ans = 0; 62 cin >> n >> m >> k; 63 while (m--) 64 { 65 int u, v; 66 ll cost; 67 cin >> u >> v >> cost; 68 G[u].push_back(edge{v, cost}); 69 G[v].push_back(edge{u, cost}); 70 } 71 memset(tmp, 0, sizeof(tmp)); 72 memset(in, 0, sizeof(in)); 73 while (k--) 74 { 75 int u; 76 ll cost; 77 cin >> u >> cost; 78 if (!tmp[u]) tmp[u] = cost; 79 else 80 { 81 tmp[u] = min(tmp[u], cost); 82 ans++; 83 } 84 } 85 for (int i = 2; i <= n; ++i) 86 { 87 if (!tmp[i]) continue; 88 else 89 { 90 G[i].push_back(edge{1, tmp[i]}); 91 G[1].push_back(edge{i, tmp[i]}); 92 } 93 } 94 dijkstra(1); 95 //for (int i = 2; i <= n; ++i) cout << in[i] << ' '; 96 //cout << endl; 97 //cout << ans << endl; 98 for (int i = 2; i <= n; ++i) 99 { 100 if (tmp[i]) 101 { 102 if (tmp[i] > d[i]) ans++; 103 else if (tmp[i] == d[i]) 104 { 105 if (in[i] > 1) 106 ans++; 107 } 108 } 109 } 110 cout << ans; 111 return 0; 112 }