Educational Codeforces Round 54 (Rated for Div. 2) D. Edge Deletion

地址:http://codeforces.com/contest/1076/problem/D

因为di定义为是图上1到i点的最短路径的长度,如果不限制边数,那么最少需要就是n - 1条边,使得n个点用最短路径边连起来,迪杰斯特拉就是用已知最短路的点去更新其他点,那么其他点的最短路一定会经过已知最短路的点,题中要求留k条边good点最多,那肯定是最短路上的点,k是1,有两个good点,k为2,有三个good点,。。。。类推下去,k >= n - 1,有n个good点,所以只要用迪杰斯特拉跑一遍最短路找到路径上的边即可,只需找到前k个(k < n - 1) 或n - 1个边;

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
const int N = 3 * 1e5 + 5;

LL dis[N];
bool vis[N];
vector<pair<int,pair<int,int> > >ve[N];
typedef struct Node{
    LL w;
    int x,id;
    friend bool operator < (const Node &p,const Node &q)
    {
        return p.w > q.w;
    }
}Node;
priority_queue<Node>que;
vector<int>ans;

int main()
{
    int n,m,k;
    scanf("%d %d %d",&n,&m,&k);
    for(int i = 1;i <= m;++i){
        int u,v,w;
        scanf("%d %d %d",&u,&v,&w);
        ve[u].pb(mp(w,mp(v,i)));
        ve[v].pb(mp(w,mp(u,i)));
    }
    memset(dis,inf,sizeof(dis));
    memset(vis,false,sizeof(vis));
    dis[1] = 0;
    que.push((Node){0,1,0});
    while(!que.empty())
    {
        Node tmp = que.top();
        que.pop();
        if(vis[tmp.x]) continue;
        vis[tmp.x] = true;
        if(tmp.id) ans.pb(tmp.id);
        if(ans.size() == n - 1 || ans.size() == k) break;
        int len = ve[tmp.x].size();
        for(int i = 0;i < len;++i){
            int v = ve[tmp.x][i].se.fi;
            int id = ve[tmp.x][i].se.se;
            LL w = ve[tmp.x][i].fi;
            if(!vis[v] && dis[tmp.x] + w < dis[v]){
                dis[v] = dis[tmp.x] + w;
                que.push((Node){dis[v],v,id});
            }
        }
    }
    printf("%d\n",ans.size());
    for(int i = 0;i < ans.size();++i){
        printf("%d ",ans[i]);
    }
    printf("\n");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值