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

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

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

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

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> P;
const int maxn = 3e5+;
const LL INF = 1e18;
vector<int>ans;
int n, m, k;
struct node{
LL to,cost;
node() {}
node(LL a, LL b) :to(a), cost(b) {}
};
vector<node> e[maxn];
LL vis[maxn], f[maxn], dis[maxn];
map<P,LL>mp;
void SPFA(int s)
{
for (int i = ; i < maxn; i++) {
vis[i] = ; f[i] = ;
dis[i] = INF;
}
dis[s] = ;
vis[s] = ; f[s]++;
queue<int>Q;
Q.push(s);
while (!Q.empty()) {
int t = Q.front(); Q.pop();
vis[t] = ;
for (int i = ; i < e[t].size(); i++) {
LL tmp = e[t][i].to;
if (dis[tmp] > dis[t] + e[t][i].cost) {
dis[tmp] = dis[t] + e[t][i].cost;
if (!vis[tmp]) {
vis[tmp] = ;
Q.push(tmp);
if (++f[tmp] > n)return;
}
}
}
}
return;
}
void BFS(LL x)
{
ans.clear();
queue<node>Q;
memset(vis,,sizeof(vis));
Q.push(node(x,));
vis[x] = ;
while(!Q.empty()&&ans.size()<k){
node dep = Q.front();Q.pop();
for(int i=;i<e[dep.to].size();i++){
LL to = e[dep.to][i].to;
if(ans.size()>n-&&ans.size()<k){
ans.push_back(mp[make_pair(dep.to,to)]);
continue;
}
if(ans.size()==k)return;
if(vis[to])continue;
if((dep.cost+e[dep.to][i].cost)>dis[to])continue;
ans.push_back(mp[make_pair(dep.to,to)]);
vis[to] = ;
Q.push(node(to,dep.cost+e[dep.to][i].cost));
if(ans.size()==k)return;
}
}
}
int main()
{
ios::sync_with_stdio(false);
while (cin >> n >> m >> k) {
mp.clear();
for(int i=;i<=n;i++)e[i].clear();
for (LL a, b, c, i = ; i <= m; i++) {
cin >> a >> b >> c;
e[a].push_back(node(b, c));
e[b].push_back(node(a, c));
mp[make_pair(a,b)] = i;
mp[make_pair(b,a)] = i;
// cout<<mp[make_pair(a,b)]<<endl;
}
if(k==){
cout<<""<<endl;
continue;
}
SPFA();
BFS();
cout<<ans.size()<<endl;
for(int i=;i<ans.size()-;i++)
cout<<ans[i]<<" ";
cout<<ans[ans.size()-]<<endl;
}
return ;
}

最新文章

  1. android和ubifs
  2. seafile
  3. 文件和目录之设置用户ID和设置组ID
  4. hdu 4686 Arc of Dream(矩阵快速幂乘法)
  5. POIXV Permutation
  6. 201521123090 《Java程序设计》第4周学习总结
  7. html5的video标签自动播放
  8. Loj #2542. 「PKUWC2018」随机游走
  9. SQL Server - Partition by 和 Group by对比
  10. numpy 数组对象
  11. Python写黑客小工具,360免杀
  12. Linux性能分析流程图
  13. LigerUI子父窗口之间传参问题
  14. 【LeetCode每天一题】Permutations(排列组合)
  15. keras 分类回归 损失函数与评价指标
  16. 安装mysql时启动服务出错问题
  17. Haskell语言学习笔记(25)MonadState, State, StateT
  18. Android之build.prop属性详解
  19. 关于mysqli_free_result($result)报错
  20. 永久解决delphi 2010不能2次启动问题

热门文章

  1. golang数据类型二
  2. python的数据类型和变量
  3. 使用 Windows 10 WSL 搭建 ESP8266 编译环境并使用 VSCODE 编程(一)(2019-08-23)
  4. 自定义连接池DataSourse
  5. docker-compose进入容器出现unable to find user root: no matching entries in passwd file
  6. Web富媒体应用
  7. Python小技巧整理
  8. oracle 创建新表,并复制旧表数据
  9. iOS 后台定位
  10. 亲测的orabbix监控Oracle过程