zoukankan      html  css  js  c++  java
  • CF1076D Edge Deletion

    题目大意:给定 N 个点 M 条边的无向简单联通图,留下最多 K 条边,求剩下的点里面从 1 号顶点到其余各点最短路大小等于原先最短路大小的点最多怎么构造。

    这个题贪心+dijkstra

    我们可以在第一次跑 dij 时直接采用贪心策略,即:若当前答案集合的大小小于 K 且优先队列非空,则继续优先队列遍历,每次把一条边加入到答案集合中。

    因为是在求解最短路过程中向答案集合中加边,可知这就是一种最优策略。

    #define B cout << "BreakPoint" << endl;
    #define O(x) cout << #x << " " << x << endl;
    #define O_(x) cout << #x << " " << x << " ";
    #define Msz(x) cout << "Sizeof " << #x << " " << sizeof(x)/1024/1024 << " MB" << endl;
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<set>
    #define LL long long
    const int inf = 1e9 + 9;
    const int N = 5e5 + 5;
    using namespace std;
    inline int read() {
    	int s = 0,w = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {
    		if(ch == '-')
    			w = -1;
    		ch = getchar();
    	}
    	while(ch >= '0' && ch <= '9') {
    		s = s * 10 + ch - '0';
    		ch = getchar();
    	}
    	return s * w;
    }
    typedef pair<LL,int> pii;
    struct node{
        int nxt,to,w;
    }e[N<<1];
    int head[N],n,m,k,pre[N],vis[N],tot = 1;
    inline void add(int x,int y,int w){
        e[++tot] = node{head[x],y,w},head[x] = tot;
    }
    LL dis[N];
    vector<int> ans;
    priority_queue<pii> q;
    void init(){
        n = read(),m = read(),k = read();
        for(int i = 1;i <= m;i++){
            int x = read(),y = read(),w = read();
            add(x,y,w),add(y,x,w);
        }
    }
    void dij(){
        for(int i = 2;i <= n;i++) dis[i] = 1e15;
        q.push(make_pair(0,1));
        while(!q.empty() && ans.size() < k){
            int u = q.top().second;
    		q.pop();
            if(vis[u]) continue;
            if(u ^ 1) ans.push_back(pre[u] / 2);
            vis[u] = 1;
            for(int i = head[u];i;i = e[i].nxt){
                int v = e[i].to,w = e[i].w;
                if(dis[v] > dis[u] + w){
                    dis[v] = dis[u] + w,pre[v] = i;
                    q.push(make_pair(-dis[v],v));
                }
            }
        }
    }
    void solve(){
        dij();
        k = ans.size();
        printf("%d
    ",k);
        for(int i = 0;i < k;i++) printf("%d ",ans[i]);
    }
    int main(){
        init();
        solve();
        return 0;
    }
    
  • 相关阅读:
    往excel中插入分组柱状图
    往excel中插入柱状图b
    向excel中插入柱状图a
    对excel进行数据筛选及过滤
    对excel进行排序及多重排序
    函数填充,计算列
    ChinaCock界面控件介绍-TCCImageViewerForm
    Allocation-Free Collections
    Delphi 10.3实现Android App的动态权限申请
    DeployMan,发布文件的利器
  • 原文地址:https://www.cnblogs.com/excellent-zzy/p/12404923.html
Copyright © 2011-2022 走看看