Codeforces 449B Jzzhu and Cities

题目链接: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 }
原文地址:https://www.cnblogs.com/veasky/p/11270926.html