首页 > 代码库 > Codeforces 449B Jzzhu and Cities(最短路)

Codeforces 449B Jzzhu and Cities(最短路)

题目链接:Codeforces 449B Jzzhu and Cities

题目大意:Jzzhu是一个国家的总统,这个国家有N座城市,以1为首都,已经存在了M条公路,给定M条路。并且还有K条铁轨,铁轨均有首都出发,连接si,距离为yi。现在Jzzhu想要节省经费,拆除一些铁轨,问说最多能拆除多少个铁轨,要求每座城市与首都的最短距离不变。

解题思路:最短路,多加一个标记数组,每个si标记1,如果这些点的最短距离被更新,则将对应si的标记清为0,最后统计一下剩余的标记,即为不能拆除的铁轨。

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 1e5 + 5;
const ll INF = 0x3f3f3f3f3f3f3f3f;

int N, M, K, p[maxn], vis[maxn];
ll d[maxn];
vector<pii> g[maxn];

void init () {
    scanf("%d%d%d", &N, &M, &K);
    int u, v, x;
    for (int i = 0; i < M; i++) {
        scanf("%d%d%d", &u, &v, &x);
        g[u].push_back(make_pair(v, x));
        g[v].push_back(make_pair(u, x));
    }
}

int solve () {
    for (int i = 0; i <= N; i++)
        d[i] = INF;
    d[1] = 0;

    memset(p, 0, sizeof(p));
    queue<int> que;
    vis[1] = 1;
    que.push(1);

    for (int i = 1; i <= K; i++) {
        int u, x;
        scanf("%d%d", &u, &x);
        if (d[u] > x) {
            d[u] = x; p[u] = 1;

            if (vis[u] == 0) {
                vis[u] = 1;
                que.push(u);
            }
        }
    }

    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].first, x = g[u][i].second;

            if (d[v] >= d[u] + x && p[v])
                p[v] = 0;

            if (d[v] > d[u] + x) {
                d[v] = d[u] + x;
                if (vis[v] == 0) {
                    vis[v] = 1;
                    que.push(v);
                }
            }
        }
    }

    for (int i = 1; i <= N; i++)
        K -= p[i];
    return K;
}

int main () {
    init();
    printf("%d\n", solve());
    return 0;
}

Codeforces 449B Jzzhu and Cities(最短路)