题意:
n个点m条边的无向连通图(无自环、重边),现在要删除一些边使得图最多剩下k条边,并且这样的点尽量多:这个点到1号节点的最短路不变
思路:
建出最短路树,统计边数,然后跑一遍dfs,在回溯的时候判断边数与k的关系,若边数>k就使边数减一,否则记录答案
#include
using namespace std;
const int maxn = 3e5 + 10;
typedef long long ll;
const ll INF = 1e16;
typedef pair P;
int n, m, k;
int tot, head[maxn];
struct Edge {
int to, cost, id, next;
}edges[2*maxn];
void init_edges() {
tot = 0;
memset(head, -1, sizeof(head));
}
void addedge(int from, int to, int cost, int id) {
edges[tot].to = to;
edges[tot].cost = cost;
edges[tot].id = id;
edges[tot].next = head[from];
head[from] = tot++;
}
bool vis[maxn];
ll dis[maxn];
struct Path {
int to;
int id;
}path[maxn];
void dijkstra() {
memset(vis, 0, sizeof(vis));
for (int i = 0;
i < maxn;
i++) dis[i] = INF;
memset(path, 0, sizeof(path));
int s = 1;
dis[s] = 0;
priority_queue, greater > que;
que.push(make_pair(0, s));
while (!que.empty()) {
int u = que.top().second;
que.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i = head[u];
~i;
i = edges[i].next) {
int v = edges[i].to, cost = edges[i].cost, id = edges[i].id;
if (dis[v] > dis[u] + cost) {
dis[v] = dis[u] + cost;
path[v].to = u;
path[v].id = id;
que.push(make_pair(dis[v], v));
}
}
}
}
int cnt;
void dfs(int u) {
if (u == 0) return;
if (vis[u]) return;
vis[u] = 1;
int v = path[u].to, id = path[u].id;
if (v == 0) return;
addedge(v, u, 1, id);
cnt++;
dfs(v);
}
vector ans;
void solve(int u) {
for (int i = head[u];
~i;
i = edges[i].next) {
int v = edges[i].to, id = edges[i].id;
solve(v);
if (cnt > k) {
cnt--;
}
else {
ans.push_back(id);
}
}
}
int main() {
scanf("%d%d%d", &n, &m, &k);
init_edges();
for (int i = 1;
i <= m;
i++) {
int u, v, cost;
scanf("%d%d%d", &u, &v, &cost);
addedge(u, v, cost, i);
addedge(v, u, cost, i);
}
dijkstra();
cnt = 0;
init_edges();
memset(vis, 0, sizeof(vis));
for (int i = 2;
i <= n;
i++) {
dfs(i);
}
ans.clear();
solve(1);
sort(ans.begin(), ans.end());
printf("%d\n", ans.size());
for (int i = 0;
i < ans.size();
i++) {
printf("%d", ans[i]);
if (i == ans.size()-1) printf("\n");
else printf(" ");
}
return 0;
}
【Codeforces 1076D Edge Deletion——最短路+dfs】
推荐阅读
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)
- 求桥,边双连通缩点
- 玩一玩|超立方体及其可视化(Processing)
- #|【牛客】牛客练习赛67-E-牛妹游历城市——位运算优化
- 图论|POJ1364 King 差分约束
- 图论|tarjan算法之——割点和桥
- 线段树|FZU - 2277(树链剖分或dfs序+线段树)
- 贪心|Codeforces D. Solve The Maze (bfs & 贪心) (Round #648 Div.2)
- online|hdu4115Eliminate the Conflict