• 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
  • 相关阅读:
    每天一个命令
    2017-2-21
    egrep []+ 和awk总结
    ifconfig eth0 取行取列
    stat /etc/hosts 取行取列644
    压缩解压缩
    目录
    公告
    To do list
    CSP 2019 游记
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9958839.html
Copyright © 2020-2023  润新知