题目描述

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. spring--AOP--日志---demo1---bai

    AOP日志DEMO1: 实体类: package com.etc.entity; import org.aspectj.lang.annotation.Pointcut; public class U ...

  2. app中使用微信分享注意事项

    1.  在微信公众平台开通一个微信公众号,https://mp.weixin.qq.com 2.  将自己制作好的已签名的app安装到手机上 3.  下载微信开放平台获取应用签名的apk--- gen ...

  3. Android指针管理:RefBase,SP,WP

    Android中通过引用计数来实现智能指针,并且实现有强指针与弱指针.由对象本身来提供引用计数器,但是对象不会去维护引用计数器的值,而是由智能指针来管理. 要达到所有对象都可用引用计数器实现智能指针管 ...

  4. MSSQL grant权限

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

  5. 4-3 set与delete命令的使用_(有一处打点 内容不确定)

    那么既然有create创建操作,那么也就有改操作,也就是我们平时所说的增删改.它使用的是set命令去修改它的节点. set path data [version] verision是可以写也可以不写. ...

  6. JDBC MySQL 实例之 用户管理系统

    1 Java 和 MySQL 怎么建立连接 2 通过Java怎么对数据库进行操作 package day01; import java.sql.Connection; import java.sql. ...

  7. SQLServer+.net 事务锁表问题

    最近操作Sqlserver遇到一个锁表问题.找了好久才搞明白原因和解决办法. 故障现象: 每次启动事务后,执行了删除或者修改操作以后,再执行查询操作就锁表. 解决过程: 1:最初以为SQLServer ...

  8. OpenGL超级宝典完整源码(第五版)

    链接:https://pan.baidu.com/s/1dGQkk4T 密码:wu44 Visual Studio 2017配置OpenGL https://blog.csdn.net/qiangbi ...

  9. 在Ubuntu里启用root账号

    我的系统环境, 操作系统:Win7 虚拟机软件:VMware workstation 12 在虚拟机里安装了Ubuntu 18,安装时的账号frank,在安装其它软件的时候,报权限不足,因此,准备启用 ...

  10. 后台执行UNIX/Linux命令和脚本的五种方法

    hiveserver 后台启动 nohup "${HIVE_HOME}"/bin/hive --service hiveserver2 & 1. 使用&符号在后台执 ...