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


    题目链接:http://codeforces.com/contest/1076/problem/D

    题目大意:

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

       (2≤n≤3⋅105, 1≤m≤3⋅105, n−1≤m, 0≤k≤m)

    解题思路:太菜了没写出来。。。

    参考自博客:https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/9951711.html

    用迪杰斯特拉在图中跑最短路,并且利用两个数组存被松弛节点的父节点和保存对应的边,然后用bfs贪心保留离源点近的边。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=3e5+5;
    int n,m,k;
    struct qnode{
        int v;
        ll d;
        qnode(int a,ll b):v(a),d(b){}
        bool operator<(const qnode& x)const{
            return d>x.d;
        }
    };
    struct edge{
        int id,v;
        ll w;
        edge(int a,int b,ll c):id(a),v(b),w(c){}
    };
    vector<edge> mp[maxn];
    void add(int id,int u,int v,ll w)
    {
        mp[u].push_back(edge(id,v,w));
        mp[v].push_back(edge(id,u,w));
    }
    int vis[maxn],pree[maxn],pret[maxn];
    ll dis[maxn];
    priority_queue<qnode> pq;
    void dij()
    {
        memset(vis,0,sizeof(vis));
        memset(dis,0x3f3f3f3f,sizeof(dis));
        dis[1]=0;
        pret[1]=1;
        pq.push(qnode(1,0));
        while(!pq.empty())
        {
            qnode q=pq.top();
            pq.pop();
            int u=q.v;
            if(vis[u]) continue;
            vis[u]=1;
            for(int i=0;i<mp[u].size();i++)
            {
                int id=mp[u][i].id;
                int v=mp[u][i].v;
                ll w=mp[u][i].w;
                if(!vis[v]&&dis[v]>dis[u]+w)
                {
                    dis[v]=dis[u]+w;
                    pret[v]=u;
                    pree[v]=id;
                    pq.push(qnode(v,dis[v]));
                }
            }
        }
    }
    vector<int> son[maxn];
    queue<int> que;
    vector<int> ans;
    void bfs()
    {
        que.push(1);
        while(!que.empty())
        {
            int u=que.front();
            que.pop();
            for(int i=0;i<son[u].size();i++)
            {
                int v=son[u][i];
                if(k>0)
                {
                    ans.push_back(pree[v]);
                    que.push(v);
                    k--;
                }
                else break;
            }
        }
    }
    
    
    int main()
    {
        ios_base::sync_with_stdio(false); cin.tie(0);
        cin>>n>>m>>k;
        for(int i=1;i<=m;i++)
        {
            int u,v;
            ll w;
            cin>>u>>v>>w;
            add(i,u,v,w);
        }
        dij();
        for(int i=2;i<=n;i++)
            son[pret[i]].push_back(i);
        bfs();
        cout<<ans.size()<<endl;
        if(ans.size()==0)
            return 0;
        cout<<ans[0];
        for(int i=1;i<ans.size();i++)
            cout<<" "<<ans[i];
        cout<<endl;
        return 0;
    }
  • 相关阅读:
    SpringMVC文件下载
    Servlet3.0文件上传
    SpringMVC拦截器的使用(入门)
    SpringMVC文件上传
    SpringMVC后台数据校验
    SpringMVC@InitBinder使用方法
    C++ this指针
    C++ 析构函数
    C++ 构造函数
    C++ 成员函数的实现
  • 原文地址:https://www.cnblogs.com/zjl192628928/p/10008814.html
Copyright © 2020-2023  润新知