题目描述

You are given an undirected connected weighted graph consisting of n n n vertices and m m m edges. Let's denote the length of the shortest path from vertex 1 1 1 to vertex i i i as di d_i di​ .

You have to erase some edges of the graph so that at most k k k edges remain. Let's call a vertex i i i good if there still exists a path from 1 1 1 to i i i with length di d_i di​ after erasing the edges.

Your goal is to erase the edges in such a way that the number of good vertices is maximized.

输入输出格式

输入格式:

The first line contains three integers n n n , m m m and k k k ( 2≤n≤3⋅105 2 \le n \le 3 \cdot 10^5 2≤n≤3⋅105 , 1≤m≤3⋅105 1 \le m \le 3 \cdot 10^5 1≤m≤3⋅105 , n−1≤m n - 1 \le m n−1≤m , 0≤k≤m 0 \le k \le m 0≤k≤m
) — the number of vertices and edges in the graph, and the maximum
number of edges that can be retained in the graph, respectively.

Then m m m lines follow, each containing three integers x x x , y y y , w w w ( 1≤x,y≤n 1 \le x, y \le n 1≤x,y≤n , x≠y x \ne y x≠y , 1≤w≤109 1 \le w \le 10^9 1≤w≤109 ), denoting an edge connecting vertices x x x and y y y and having weight w w w .

The given graph is connected (any vertex can be reached from any
other vertex) and simple (there are no self-loops, and for each
unordered pair of vertices there exists at most one edge connecting
these vertices).

输出格式:

In the first line print e e e — the number of edges that should remain in the graph ( 0≤e≤k 0 \le e \le k 0≤e≤k ).

In the second line print e e e distinct integers from 1 1 1 to m m m
— the indices of edges that should remain in the graph. Edges are
numbered in the same order they are given in the input. The number of
good vertices should be as large as possible.

输入输出样例

输入样例#1:
复制

3 3 2
1 2 1
3 2 1
1 3 3
输出样例#1: 复制

2
1 2
输入样例#2: 复制

4 5 2
4 1 8
2 4 1
2 1 3
3 4 9
3 1 5
输出样例#2: 复制

2
3 2 n 个点 m条边的连通图,只能最多保留K条边,最后要满足从1出发到其他节点最短距离不变的点最多,问方案(边)
先 dijkstra 一下,保存一下父亲和儿子节点以及边的编号;
最后 bfs一下,每次如果此时的 K>0,那么就选择改边;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 400005
#define inf 0x3f3f3f3f
#define INF 9999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
typedef pair<int, int> pii;
inline ll rd() {
ll x = 0;
char c = getchar();
bool f = false;
while (!isdigit(c)) {
if (c == '-') f = true;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f ? -x : x;
} ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; } /*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) {
x = 1; y = 0; return a;
}
ans = exgcd(b, a%b, x, y);
ll t = x; x = y; y = t - a / b * y;
return ans;
}
*/ ll qpow(ll a, ll b, ll c) {
ll ans = 1;
a = a % c;
while (b) {
if (b % 2)ans = ans * a%c;
b /= 2; a = a * a%c;
}
return ans;
} int n, m, k;
int head[maxn<<1];
struct node {
int to;
ll dis;
node(){}
node(int to,ll dis):to(to),dis(dis){} bool operator < (const node&rhs)const {
return dis > rhs.dis;
}
}edge[maxn<<1]; struct Edge {
int id;
int v; ll w;
int nxt; Edge(){}
Edge(int id,int v,int w):id(id),v(v),w(w){} }EDGE[maxn<<1]; ll dis[maxn];
bool vis[maxn];
int fath[maxn], fathedge[maxn];
vector<Edge>G[maxn]; void addedge(int i, int u, int v, int w) {
G[u].push_back(Edge(i, v, w)); G[v].push_back(Edge(i, u, w));
} priority_queue<node>pq; void dijkstra() {
memset(dis, 0x3f, sizeof(dis)); ms(vis);
dis[1] = 0; vis[1] = 0;
fath[1] = 1;
pq.push(node(1, 0));
while (!pq.empty()) {
node tmp = pq.top(); pq.pop();
int u = tmp.to;
if (vis[u])continue; vis[u] = 1;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i].v;
if (dis[v] > dis[u] + (ll)G[u][i].w) {
dis[v] = dis[u] + (ll)G[u][i].w;
fath[v] = u; fathedge[v] = G[u][i].id;
pq.push(node(v, (ll)dis[v]));
}
}
}
} vector<int>son[maxn];
vector<int>res;
queue<int>q; void bfs() {
q.push(1);
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i = 0; i < son[u].size(); i++) {
int v = son[u][i];
if (k > 0) {
res.push_back(fathedge[v]); q.push(v); k--;
}
else
break;
}
}
} int main()
{
//ios::sync_with_stdio(0);
rdint(n); rdint(m); rdint(k);
for (int i = 1; i <= m; i++) {
int u, v, w; rdint(u); rdint(v); rdint(w);
addedge(i, u, v, w);
}
dijkstra();
for (int i = 2; i <= n; i++) {
son[fath[i]].push_back(i);
}
bfs();
cout << res.size() << endl;
for (int i = 0; i < res.size(); i++) {
cout << res[i] << ' ';
}
cout << endl;
return 0;
}

CF1076D Edge Deletion 最短路径树+bfs的更多相关文章

  1. CF1076D Edge Deletion

    洛谷传送门 cf传送门 这道题作为div.2的D题,被我一眼秒了我觉得十分荣幸,然后就开始写,然后就写了好久. AC之后看网上的题解,发现好多最短路树的,猛然发现我写的好复杂啊,结果还看到了直接一遍d ...

  2. CF1076D Edge Deletion 最短路树

    问题描述 Codeforces 洛谷(有翻译) 题解 最短路树,是一棵在最短路过程中构建的树. 在\(\mathrm{Dijkstra}\)过程中,如果最终点\(y\)是由点\(x\)转移得到的,则在 ...

  3. bzoj 4016 [FJOI2014]最短路径树问题(最短路径树+树分治)

    4016: [FJOI2014]最短路径树问题 Time Limit: 5 Sec  Memory Limit: 512 MBSubmit: 426  Solved: 147[Submit][Stat ...

  4. Codeforces 1076D Edge Deletion(最短路树)

    题目链接:Edge Deletion 题意:给定一张n个顶点,m条边的带权无向图,已知从顶点1到各个顶点的最短路径为di,现要求保留最多k条边,使得从顶点1到各个顶点的最短距离为di的顶点最多.输出m ...

  5. [BZOJ4016][FJOI2014]最短路径树问题

    [BZOJ4016][FJOI2014]最短路径树问题 试题描述 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多条长 ...

  6. HDU4871 Shortest-path tree(最短路径树 + 树的点分治)

    题目大概要先求一张边有权的图的根为1的最短路径树,要满足根到各点路径序列的字典序最小:然后求这棵最短路径树包含k个结点的最长路径的长度和个数. 首先先构造出这棵字典序最小的最短路径树..好吧,我太傻逼 ...

  7. POJ3013 Big Christmas Tree(最短路径树)

    题目大概说给一张点和边都有权的图,现在要求其一棵以1结点为根的生成树使树的边权和最小,树边权 = 对应的图边权 * 树边末端点为根的子树所有结点对于图顶点的点权和. 要求∑(边权*子树点权和),等价于 ...

  8. LA 4080 (多源最短路径+边修改+最短路径树)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32266 题目大意:①先求任意两点间的最短路径累加和,其中不连通的边 ...

  9. [FJOI 2014]最短路径树问题

    Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多条长度最短的路径,则选择经过的顶点序列字典序最 ...

随机推荐

  1. web编程的初步认识

    一直以后, 只知道打开浏览器, 输入网址便可以上网浏览网页, 但是当认真琢磨起这web编程的时候, 对于很多细节却是感觉很迷惑, 在慢慢的学习中, 才逐渐有了些了解. web有client/serve ...

  2. ES6相关实用特性

    本文总结ECMAScript6相关实用特性 目录 let和const 箭头函数 class 对象字段 模板字符串 解构赋值 函数参数扩展 迭代器for...of 模块加载 map和weakmap se ...

  3. 第五章 Java中锁

    Lock接口 锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源(但是有些锁可以允许多个线程并发的访问共享资源,比如读写锁).在Lock接口出现之前,Java程序 ...

  4. noip2017D2T3的几种写法...(BIT/线段树/平衡树)

    题意各大oj上都有啦..想必来搜题解的都看过题面了...Qw Solution1: 首先观察n=1的情况,显然就是中间删掉一个数后面加上一个数,并查询那个删掉的数(以后把这样一个过程称为一个操作啦(( ...

  5. hadoop再次集群搭建(4)-Cloudera Manager Installation

       决定选择 Cloudera Manager 进行安装,阅读官方文档,掌握大概脉络.         Cloudera Manager在集群已经实现ssh免秘钥登录,能够访问网络资源和本地资源的情 ...

  6. Markdown编辑器及图床推荐

    Typora和自动图床工具 Typora 地址 ,极致简洁,界面很漂亮,最重要的是所见即所得 百度云搬运 密码:xi01 自动图床工具 需要七牛云做图床,感谢作者,详见博客 使用方法,只需两步即可完成 ...

  7. 使用LaTeX按IEEE模板写论文时的参考文献管理方法(BibTeX使用小结)

    之前用LaTeX写论文时,参考文献都是手动添加管理的,真是让人很抓狂.所以这次趁着假期,简单看了一下怎么使用BibTeX对参考文献进行管理,这里以IEEE的最新模板为例. 首先说明,我之前用的是MiK ...

  8. 昨天的笔试题, StringBuffer

    代码: public static void switchStr(StringBuffer x, StringBuffer y) { x.append(y); System.out.println(& ...

  9. spring配置c3p0连接池

  10. MSSQL grant权限

    --创建登录名 create login test_user with password='123456a.'; --创建用户 create user test_user for login test ...