Codeforces1076D. Edge Deletion(最短路树+bfs)
题目大意:
一个图N个点M条双向边。设各点到点1的距离为di,保证满足条件删除M-K条边之后使得到点1的距离仍为di的点数量最多的情况下,输出剩余的K条边的编号(按输入顺序)。
一道大水题 , 应为网络原因没有看到题目, 赛后发现就是跑一遍DJ最短路就好了 , 在最短路里面拿出k条边, 大水题呀。。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAX_N = 3e5 + 5; int N, M, K; struct PQNode{ int v; ll dis; PQNode(int _v = 0, ll _dis = 0) : v(_v), dis(_dis) {} bool operator < (const PQNode& x) const { return dis > x.dis; } }; struct Edge{ int id, v; ll w; Edge(int _id = 0, int _v = 0, ll _w = 0) : id(_id), v(_v), w(_w) {} }; vector <Edge> E[MAX_N]; void addEdge(int i, int u, int v, ll w) { E[u].push_back(Edge(i, v, w)); E[v].push_back(Edge(i, u, w)); } bool vis[MAX_N]; ll dist[MAX_N]; int fat[MAX_N], faEdge[MAX_N]; priority_queue <PQNode> PQ; void Dijkstra() { memset(dist, 0x3f, sizeof dist); memset(vis, false, sizeof vis); dist[1] = 0; fat[1] = 1; PQ.push(PQNode(1, 0)); while (!PQ.empty()) { int u = PQ.top().v; PQ.pop(); if (vis[u]) continue; vis[u] = true; for (int i = 0; i < (int)E[u].size(); i++) { int id = E[u][i].id; int v = E[u][i].v; ll w = E[u][i].w; if (vis[v]) continue; if (dist[v] > dist[u] + w) { dist[v] = dist[u] + w; fat[v] = u; faEdge[v] = id; PQ.push(PQNode(v, dist[v])); } } } } vector <int> son[MAX_N]; queue <int> BQ; vector <int> ans; void bfs() { BQ.push(1); while (!BQ.empty() && K > 0) { int u = BQ.front(); BQ.pop(); for (int i = 0; i < (int)son[u].size(); i++) { int v = son[u][i]; if (K > 0) { ans.push_back(faEdge[v]); BQ.push(v); K--; } else break; } } } int main() { cin >> N >> M >> K; for (int i = 1; i <= M; i++) { int u, v; ll w; scanf("%d%d%lld", &u, &v, &w); addEdge(i, u, v, w); } Dijkstra(); for (int i = 2; i <= N; i++) son[fat[i]].push_back(i); bfs(); cout << ans.size() << endl; bool firstprint = true; for (int i = 0; i < (int)ans.size(); i++) { if (firstprint) firstprint = false; else printf(" "); printf("%d", ans[i]); } puts(""); return 0; } /* 3 2 2 1 2 1 3 3 */