Jzzhu and Cities CodeForces - 449B
1.题意介绍
一个总统为了他们国家减少花费想要直接关闭一些铁路路线,但需要要求首都到每个城市的最短路长不会发生改变。
2.做法
(1) 建图后跑最短路,找首都到每个城市的最短路。
(2) 当火车路线大于首都到每一点的最短路时,这条铁路就是可以拆除的。
(3) 当火车路线等于最短路时怎么办呢?
我们可以在跑最短路时个入度。if (dis[v] > dis[u] + ed[i].w) in[v] = 1;
而当 if (dis[v] == dis[u] + ed[i].w) 则存在多选情况in[v]++;
#include <bits/stdc++.h>
using namespace std;
const long long inf = 1e18;
const int maxn = 2000100;
#define ll long long
int n, m, k;
long long head[maxn], cnt, dis[maxn], tot, sum;
long long vis[maxn], in[maxn], g[maxn], v[maxn];
struct edge {
long long u, v, w, ne;
};
edge ed[maxn];
void init() {
cnt = 0;
for (int i = 0; i <= n; i++) {
dis[i] = inf, vis[i] = 0, head[i] = -1, in[i] = 0;
}
}
void addedge(ll u, ll v, ll w) {
ed[cnt].u = u; ed[cnt].v = v; ed[cnt].w = w;
ed[cnt].ne = head[u]; head[u] = cnt++;
}
void spfa(int st) { // spfa+优化的最短路
deque<int>q;
dis[st] = 0; vis[st] = 1; tot = 1, sum = 0;
q.push_front(st);
while (!q.empty()) {
int u = q.front();
q.pop_front(); vis[u] = 0;
tot--; sum -= dis[u];
for (int i = head[u]; ~i; i = ed[i].ne) {
int v = ed[i].v;
if (dis[v] > dis[u] + ed[i].w) {
in[v] = 1; // 当dis[v] > dis[u] + ed[i].w时入度为1
dis[v] = dis[u] + ed[i].w;
if (!vis[v]) {
vis[v] = 1;
if (q.empty() || dis[v] > dis[q.front()] ||
dis[v] * tot >= sum) q.push_back(v);
else q.push_front(v);
tot++; sum+= dis[v];
}
}
else if(dis[v] == dis[u] + ed[i].w) in[v]++; // 相等时入读增加
}
}
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
init();
for(int i = 0; i < m; i++)
{
long long x, y, w;
scanf("%lld%lld%lld", &x, &y, &w);
addedge(x, y, w);
addedge(y, x, w);
}
for(int i = 0; i < k; i++)
{
scanf("%lld%lld", &g[i], &v[i]);
addedge(1, g[i], v[i]);
addedge(g[i], 1, v[i]);
}
long long out = 0;
spfa(1);
for(int i = 0; i < k; i++)
{
if(dis[g[i]] < v[i]) out++; // 当火车路线比最短路长时可拆除的+1
else if(dis[g[i]] == v[i])
{
if(in[g[i]] > 1)
{
in[g[i]]--;
out++; // 和最短路相等时,如果入度大于1即可有替代方案。
}
}
}
printf("%lld\n", out);
return 0;
}