题目描述

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. Word中调整编号和文字的间距

    鼠标放在节文字上,不用选择该级别的所有节点,直接在某一节上右键-段落-制表位-默认制表位-设置1字符或其它.完成后该级别所有节的格式都自动调整,不用一个个调整. 但是设置其它段落格式还是需要在菜单上选 ...

  2. 第四章 Java并发编程基础

    线程简介 什么是线程? 现代操作系统在一个运行程序时,会为其创建一个进程.例如,启动一个Java程序,操作系统就会创建一个Java进程.现代操作系统调度的最小单元是线程,也叫轻量进程(Light We ...

  3. myeclipse与eclipse的web项目部署区别

    一.myeclipse之web项目的部署(发布)流程 web项目的部署(发布)流程2008-01-18 14:35 在myeclipse下新建web工程abc.系统设置默认如下: 项目保存位置:wor ...

  4. bash: telnet: command not found

    //安装telnet服务 yum -y install telnet-server //安装telnet客户端 yum -y install telnet.*

  5. 在Linux下adb连接不上android手机的终极解决方案

    转自: http://blog.csdn.net/liuqz2009/article/details/7942569 1.做android开发的过程,碰到了Linux下adb识别不了android设备 ...

  6. Codeforces 1077(F1+F2) DP 单调队列

    题意:给你一个n个元素的数组,从中选取x个元素,并且要保证任意的m个位置中必须至少有一个元素被选中,问选中元素的和最大可以是多少? F1 n,m,x到200 F2 n,m,x到5000. 思路1:设d ...

  7. 推荐两款富文本编辑器:NicEdit和Kindeditor

    做过Web开发的朋友相信都使用过富文本编辑器,比较出名的CuteEditor和CKEditor很多人应该已经使用过,在功能强大的同时需要加载的东西也变得很多.下面要推荐的两款富文本编辑器都是使用JS编 ...

  8. varnish安装

    安装pcrevarnish 依赖pcre进行url正则匹配. cd pcre-8.12./configure --prefix=/usr/local/make&&make instal ...

  9. Linux expect命令

    一.简介 通过Shell可以实现简单的控制流功能,但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet服务器等进行交互的功能.而就使用来实现这种功能的工具.Ex ...

  10. WOJ 7 智商

    感觉Dasin去年的毒瘤题质量都挺好的,果然还是我太菜了. 以下假设划横线部分都相等,字符$c$代表一个小写字母. 分类讨论: $#1$ 先考虑$n == m$的情况 : $#1.1 :$ A:   ...