题解 CF1076D Edge Deletion

题目链接

既然题目让我们求保留 \(k\) 条边的最大好点数量,那我们首先思考这样的问题:什么情况下删一条边必定会删一个点。

显然,只有树才会出现这样的情况,而在一个连通图还没有删成树之前,删边对于点的数量是没有影响的。所以,我们考虑取原图中的一棵树,在树的基础上进行处理。

按照题目,我们应保证:树上的每个节点到 \(1\) 号节点的距离是最短路径长度,这时我们引入最短路径树(SPT)的概念。

\(dijkstra\) 求最短路(边权 \(\ge 0\))的过程中,由于每个点只会遍历一次,所以自然就形成了一棵树。对于每个节点,记录使得其取最小值的边,如果有几条边都能使其取最短路,那么依题目具体而定(如Paths and Trees,同等情况取最小边)。

按照 \(dij\) 建出 \(SPT\) 以后,从下往上进行删边,这样可以保证每次删一个点,类似于拓扑排序的过程做一遍即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
#define PII pair<LL,int>
const int N=1e6+10;
int n,m,k;
struct node {
    int to,w,id;
};
vector<node> g[N];

LL dis[N]; int vis[N];
int f[N],edge_id[N];
priority_queue<PII> q;

void dij(int st) {
    memset(dis,0x3f,sizeof(dis));
    dis[st]=0; q.push({0,st});
    while(q.size()) {
        int x=q.top().second; q.pop();
        if(vis[x]) continue;
        vis[x]=1;
        for(auto t:g[x]) {
            int y=t.to,w=t.w,id=t.id;
            if(vis[y]) continue;
            if(dis[y]>dis[x]+w) {
                dis[y]=dis[x]+w;
                f[edge_id[y]]=0; f[id]=1; edge_id[y]=id;
                q.push({-dis[y],y});
            }
        }
    }
}

int deg[N];
queue<int> qq;
int main() {
    cin>>n>>m>>k;
    for(int i=1;i<=m;i++) {
        int u,v,w; cin>>u>>v>>w;
        g[u].push_back({v,w,i});
        g[v].push_back({u,w,i});
    }

    dij(1);

    for(int i=1;i<=n;i++) {
        for(auto t:g[i]) {
            if(!f[t.id]) continue;
            deg[t.to]++;
        }
    }
    int cut_num=n-1-k;
    for(int i=1;i<=n;i++) if(i!=1&&deg[i]==1) qq.push(i);
    while(qq.size()&&cut_num>0) {
        int x=qq.front(); qq.pop();
        for(auto t:g[x]) {
            if(!f[t.id]) continue;
            deg[t.to]--; cut_num--; f[t.id]=0;
            if(deg[t.to]==1&&t.to!=1) qq.push(t.to);
            if(!cut_num) break;
        }
    }
    int cnt=0;
    for(int i=1;i<=m;i++) {
        if(f[i]) cnt++;
    }
    cout<<cnt<<endl;
    for(int i=1;i<=m;i++) if(f[i]) cout<<i<<' ';

    return 0;
}
posted @ 2023-08-12 22:41  2017BeiJiang  阅读(9)  评论(0编辑  收藏  举报