Educational Codeforces Round 54 D. Edge Deletion

题意:

n个点,m条边,删除一些边,剩下k条边,使得到节点1最短路径长度不变的节点数最多.

分析:

最短路原理题,我们考虑用dij求最短路的过程中,每加入一个新的点,都要引入一个新的边,如果k >= n,把n条关键边输出,如果k < n,在dij的过程中,直接找到k个点最短路就跳出,记录一下边的编号

参考代码

// 
#include <bits/stdc++.h>
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define Pb push_back
#define FI first
#define SE second
#define For(i,a,b) for(LL i = a; i < b; ++i)
#define IOS ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;


LL dr[2][4] = {1,-1,0,0,0,0,-1,1};
typedef pair<LL,LL> P;
#define endl "\n"
struct Edge{
    LL u,v,d;
    LL id;
    Edge(LL uu,LL vv,LL dd,LL idd):u(uu),v(vv),d(dd),id(idd){
    }
};
const LL maxn = 3e5+10;

struct Dijstra{
    #define INF 1e16
    LL N,M,S,T;
    LL K;
    typedef pair<LL,LL> P;
    vector<Edge> edges;
    vector<LL> G[maxn];
    bool done[maxn];
    LL d[maxn];
    LL p[maxn];
    void init(){
        cin>>N>>M>>K;
    // for(LL i = 1;i <= N; ++i) G[i].clear();
    // edges.clear();
    // // scanf("%d %d %d %d",&N,&M,&S,&T);
    // // cout<<N<<M<<S<<T<<endl;
        S = 1;
        LL u,v,w;
        for(LL i = 1;i <= M; ++i){
            scanf("%lld %lld %lld",&u,&v,&w);
            AddEdge(u,v,w,i);
            AddEdge(v,u,w,i);
        }
        
    }
    void AddEdge(LL u,LL v,LL d,LL id){
        edges.push_back(Edge(u,v,d,id));
        LL m = edges.size();
        G[u].push_back(m-1);    
    }
    void solve(){
        priority_queue<P,vector<P>,greater<P>> Q;
        for(LL i = 1;i <= N; ++i) d[i] = INF;
        d[S] = 0;
        memset(done,0,sizeof(done));
        Q.push(P(0,S));
        LL cnt = 0;
        std::vector<LL> v;
        while(!Q.empty()){
            P x = Q.top(); Q.pop();
            LL u = x.second;
            if(done[u]) continue;
            if(p[u] != 0)
            v.push_back(p[u]);
            cnt++;
            if(cnt == K+1)
                break;
            done[u] = true;
            for(LL i = 0;i <(LL)G[u].size(); ++i){
                Edge &e = edges[G[u][i]];
                if(!done[e.v]&&d[e.v] > d[u]+e.d){
                    d[e.v] = d[u]+e.d;
                    p[e.v] = edges[G[u][i]].id;
                    Q.push(P(d[e.v],e.v));
                }
            }
        }
        
       
        cout<<v.size()<<"\n";
        for(LL i = 0;i < (LL)v.size();++i)
            printf("%lld%c", v[i]," \n"[i==(int) v.size()-1]);
    }
};
Dijstra Dij;
int main(void)
{
  Dij.init();
  
  Dij.solve();

   return 0;
}