Codeforces1076D. Edge Deletion(最短路树+bfs)

题目大意:

  一个图N个点M条双向边。设各点到点1的距离为di,保证满足条件删除M-K条边之后使得到点1的距离仍为di的点数量最多的情况下,输出剩余的K条边的编号(按输入顺序)。

一道大水题 , 应为网络原因没有看到题目, 赛后发现就是跑一遍DJ最短路就好了 , 在最短路里面拿出k条边, 大水题呀。。

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAX_N = 3e5 + 5;

int N, M, K;
struct PQNode{
    int v;
    ll dis;
    PQNode(int _v = 0, ll _dis = 0) : v(_v), dis(_dis) {}
    bool operator < (const PQNode& x) const {
        return dis > x.dis;
    }
};
struct Edge{
    int id, v;
    ll w;
    Edge(int _id = 0, int _v = 0, ll _w = 0) : id(_id), v(_v), w(_w) {}
};
vector <Edge> E[MAX_N];
void addEdge(int i, int u, int v, ll w) {
    E[u].push_back(Edge(i, v, w));
    E[v].push_back(Edge(i, u, w));
}
bool vis[MAX_N];
ll dist[MAX_N];
int fat[MAX_N], faEdge[MAX_N];
priority_queue <PQNode> PQ;
void Dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    memset(vis, false, sizeof vis);
    dist[1] = 0;
    fat[1] = 1;
    PQ.push(PQNode(1, 0));
    while (!PQ.empty()) {
        int u = PQ.top().v;
        PQ.pop();
        if (vis[u])
            continue;
        vis[u] = true;
        for (int i = 0; i < (int)E[u].size(); i++) {
            int id = E[u][i].id;
            int v = E[u][i].v;
            ll w = E[u][i].w;
            if (vis[v])
                continue;
            if (dist[v] > dist[u] + w) {
                dist[v] = dist[u] + w;
                fat[v] = u;
                faEdge[v] = id;
                PQ.push(PQNode(v, dist[v]));
            }
        }
    }
}

vector <int> son[MAX_N];
queue <int> BQ;
vector <int> ans;
void bfs()
{
    BQ.push(1);
    while (!BQ.empty() && K > 0) {
        int u = BQ.front(); BQ.pop();
        for (int i = 0; i < (int)son[u].size(); i++) {
            int v = son[u][i];
            if (K > 0) {
                ans.push_back(faEdge[v]);
                BQ.push(v);
                K--;
            }
            else
                break;
        }
    }
}

int main()
{
    cin >> N >> M >> K;
    for (int i = 1; i <= M; i++) {
        int u, v; ll w;
        scanf("%d%d%lld", &u, &v, &w);
        addEdge(i, u, v, w);
    }
    Dijkstra();
    for (int i = 2; i <= N; i++)
        son[fat[i]].push_back(i);
    bfs();
    cout << ans.size() << endl;
    bool firstprint = true;
    for (int i = 0; i < (int)ans.size(); i++) {
        if (firstprint)
            firstprint = false;
        else
            printf(" ");
        printf("%d", ans[i]);
    }
    puts("");
    return 0;
}
/*
3 2
2 1
2 1
3 3
*/
View Code
原文地址:https://www.cnblogs.com/shuaihui520/p/9958839.html