题目大意:给定你一个包含n个点m条边的无向图,现在最多在图中保留k条边,问怎么删除多的边,使得图中良好的节点数最多,求出保留在图中的边的数量和编号。

  良好的节点定义为:删除某条边后该点到点1的最短距离不变。

思路:先求出所有点到点1的最短距离,之后再bfs一遍,若遍历到某一节点时的距离等于该点到点1的最短距离就将该条边加进去,直到添加到k条边或者遍历结束。(虽然过了但是还是觉得有有的情况好像过不了,但是没想出来...可能数据还有点水..)

  一开始INF值设小了WA了四次。。。 INF值设置1e15即可,因为边的权值很大所以上限需要很大。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<vector>
  5 #include<queue>
  6 #include<map>
  7 using namespace std;
  8 typedef long long LL;
  9 typedef pair<LL,LL> P;
 10 const int maxn = 3e5+10;
 11 const LL INF = 1e18;
 12 vector<int>ans;
 13 int n, m, k;
 14 struct node{
 15     LL to,cost;
 16     node() {}
 17     node(LL a, LL b) :to(a), cost(b) {}
 18 };
 19 vector<node> e[maxn];
 20 LL vis[maxn], f[maxn], dis[maxn];
 21 map<P,LL>mp;
 22 void SPFA(int s)
 23 {
 24     for (int i = 0; i < maxn; i++) {
 25         vis[i] = 0; f[i] = 0;
 26         dis[i] = INF;
 27     }
 28     dis[s] = 0;
 29     vis[s] = 1; f[s]++;
 30     queue<int>Q;
 31     Q.push(s);
 32     while (!Q.empty()) {
 33         int t = Q.front(); Q.pop();
 34         vis[t] = 0;
 35         for (int i = 0; i < e[t].size(); i++) {
 36             LL tmp = e[t][i].to;
 37             if (dis[tmp] > dis[t] + e[t][i].cost) {
 38                 dis[tmp] = dis[t] + e[t][i].cost;
 39                 if (!vis[tmp]) {
 40                     vis[tmp] = 1;
 41                     Q.push(tmp);
 42                     if (++f[tmp] > n)return;
 43                 }
 44             }
 45         }
 46     }
 47     return;
 48 }
 49 void BFS(LL x)
 50 {
 51     ans.clear();
 52     queue<node>Q;
 53     memset(vis,0,sizeof(vis));
 54     Q.push(node(x,0));
 55     vis[x] = 1;
 56     while(!Q.empty()&&ans.size()<k){
 57         node dep = Q.front();Q.pop();
 58         for(int i=0;i<e[dep.to].size();i++){
 59             LL to = e[dep.to][i].to;
 60             if(ans.size()>n-1&&ans.size()<k){
 61                 ans.push_back(mp[make_pair(dep.to,to)]);
 62                 continue;
 63             }
 64             if(ans.size()==k)return;
 65             if(vis[to])continue;
 66             if((dep.cost+e[dep.to][i].cost)>dis[to])continue;
 67             ans.push_back(mp[make_pair(dep.to,to)]);
 68             vis[to] = 1;
 69             Q.push(node(to,dep.cost+e[dep.to][i].cost));
 70             if(ans.size()==k)return;
 71         }
 72     }
 73 }
 74 int main()
 75 {
 76     ios::sync_with_stdio(false);
 77     while (cin >> n >> m >> k) {
 78         mp.clear();
 79         for(int i=1;i<=n;i++)e[i].clear();
 80         for (LL a, b, c, i = 1; i <= m; i++) {
 81             cin >> a >> b >> c;
 82             e[a].push_back(node(b, c));
 83             e[b].push_back(node(a, c));
 84             mp[make_pair(a,b)] = i;
 85             mp[make_pair(b,a)] = i;
 86             // cout<<mp[make_pair(a,b)]<<endl;
 87         }
 88         if(k==0){
 89             cout<<"0"<<endl;
 90             continue;
 91         }
 92         SPFA(1);
 93         BFS(1);
 94         cout<<ans.size()<<endl;
 95         for(int i=0;i<ans.size()-1;i++)
 96             cout<<ans[i]<<" ";
 97         cout<<ans[ans.size()-1]<<endl;
 98     }
 99     return 0;
100 }

View Code

转载于:https://www.cnblogs.com/wangrunhu/p/9956553.html

Educational Codeforces Round 54 (Rated for Div. 2) D Edge Deletion (SPFA + bfs)相关推荐

  1. Educational Codeforces Round 54 (Rated for Div. 2): D. Edge Deletion(最短路树)

    题意: 给你n个点m条边的无向图,其中1号节点是市中心,你现在最多只能保留k条边,并要求所有点到市中心的最短路尽量不变(也就是说设点i到点1的最短路为di,那么删边之后,要保证尽可能多的点,它到1的最 ...

  2. Educational Codeforces Round 54 (Rated for Div.2)

    Educational Codeforces Round 54 (Rated for Div.2) D. Edge Deletion 题意:一张n个点的无向图,保留其中k条边,使得有尽可能多的点与1的 ...

  3. Educational Codeforces Round 54 (Rated for Div. 2): E. Vasya and a Tree(DFS+差分)

    题意: 给你一棵n个节点的树,每个点有一个权值,初始全为0,m次操作,每次三个数(v, d, x)表示只考虑以v为根的子树,将所有与v点距离小于等于d的点权值全部加上x,求所有操作完毕后,所有节点的值 ...

  4. Educational Codeforces Round 90 (Rated for Div. 2)(A, B, C, D, E)

    Educational Codeforces Round 90 (Rated for Div. 2) Donut Shops 思路 分三种情况: a==c/ba == c / ba==c/b这个时候两 ...

  5. Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Educational Codeforces Round 114 (Rated for Div. 2) ...

  6. Educational Codeforces Round 106 (Rated for Div. 2)(A ~ E)题解(每日训练 Day.16 )

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 Educational Codeforces Round 106 (Rated for Div. ...

  7. Educational Codeforces Round 37 (Rated for Div. 2) 1

    Educational Codeforces Round 37 (Rated for Div. 2) A.Water The Garden 题意:Max想给花园浇水.花园可被视为长度为n的花园床,花园 ...

  8. Educational Codeforces Round 89 (Rated for Div. 2)(A, B, C, D)

    Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords 思路 题意非常简单,就是得到最多的物品嘛,我们假定a, ...

  9. Educational Codeforces Round 114 (Rated for Div. 2) D. The Strongest Build 暴力 + bfs

    传送门 文章目录 题意: 思路: 题意: 你有nnn个装备槽,每个槽里面有cic_ici​个力量加成,对于每个槽只能选一个力量加成,现在给你mmm个力量组合[b1,b2,...,bn][b_1,b_2 ...

最新文章

  1. ccache编译器缓存使用方法
  2. 人工智能如何推动神经科技发展?
  3. Python的lambda表达式
  4. Binder相关面试总结(三):Binder机制是如何跨进程的
  5. [基础]Linux文件说明
  6. 配置Win Server 2008 R2 防火墙允许远程访问SQL Server 2008 R2
  7. 每日 30 秒 ⏱ 唯一的数据集
  8. python初中必背语法_初中必背英语语法知识汇总
  9. 75: libreoj #10028 双向宽搜
  10. java 一维数组_java基础 ---- 一维数组
  11. 11.频域里的卷积——介绍,傅里叶变换和卷积,快速傅里叶变换(FFT)_1
  12. 新建文件夹和文件,并向文件中写入数据---------Android
  13. 如何使用Burp Suite代理
  14. sql server系统表详细说明(2)
  15. linux内核源码分析--内核启动之,Linux内核源码分析之setup_arch (二)
  16. python对称加密算法库_对称加密算法
  17. 百度 Echarts 地图-模拟迁徙,实现自动切换地图
  18. GitHub十大热门Python项目,过程很有趣
  19. 台式计算机如何上无线网络,台式电脑如何实现无线上网
  20. 外地人如何买房落户武汉 武汉户口全解读

热门文章

  1. Qt 翻译文件的加载
  2. linux 下的init 0,1,2,3,4,5,6知识介绍
  3. Mac 如何寻找Mac自带的IDLE
  4. 树莓派利用PuTTY进行远程登录
  5. 从一个基础Javascript面试题谈起
  6. 用C语言写PHP扩展 linux
  7. Enterprise Library: Logging and Instrumentation Application Block概述
  8. 100% .NET Control_自动完成Combobox的XComBo控件(VB.NET)
  9. 人口吸引力超宁波、南京,这座背靠上海的小城开挂了?
  10. 数据科学最常用流程CRISP-DM,终于有人讲明白了