CodeForces 545E Paths and Trees(最短路)

来源:互联网 发布:关于单片机的毕业设计 编辑:程序博客网 时间:2024/06/05 00:30

题目链接:http://codeforces.com/problemset/problem/545/E


题意:给一张无向联通图,让你用最短路去生成一颗最小生成树,并输出用到的边的编号


思路:在spfa的时候就可以更新记录用到哪些边了,在拥有多种最短路的时候,选择边权小的进行更新记录


#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <utility>#include <cmath>#include <queue>#include <set>#include <map>#include <climits>#include <functional>#include <deque>#include <ctime>#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;typedef long long ll;const int maxn = 300010;const ll inf = 1e16;int cnt, head[maxn];int pre[maxn], vis[maxn], val[maxn];ll dis[maxn];struct edge{int to, w, nxt, id;} e[maxn << 1];void init(){cnt = 0;memset(head, -1, sizeof(head));}void add(int u, int v, int w, int id){e[cnt].to = v;e[cnt].w = w;e[cnt].id = id;e[cnt].nxt = head[u];head[u] = cnt++;}void spfa(int s){memset(pre, 0, sizeof(pre));memset(vis, 0, sizeof(vis));for(int i = 0; i < maxn; i++) dis[i] = inf;queue <int> que;que.push(s);dis[s] = 0, vis[s] = 1;while (!que.empty()){int u = que.front();que.pop();vis[u] = 0;for (int i = head[u]; ~i; i = e[i].nxt){int v = e[i].to;//printf("*********%d %d\n", u, v);if (dis[v] > dis[u] + e[i].w){dis[v] = dis[u] + e[i].w;pre[v] = e[i].id;if (!vis[v]){vis[v] = 1;que.push(v);}}else if (dis[v] == dis[u] + e[i].w){if (e[i].w < val[pre[v]]){pre[v] = e[i].id;if (!vis[v]){vis[v] = 1;que.push(v);}}}}}}int main(){int n, m;while (~scanf("%d%d", &n, &m)){init();for (int i = 1; i <= m; i++){int u, v, w;scanf("%d%d%d", &u, &v, &w);add(u, v, w, i);add(v, u, w, i);val[i] = w;}//for(int i = 0; i < cnt; i++)//printf("%d %d %d %d\n", e[i].to, e[i].w, e[i].nxt, e[i].id);int s;scanf("%d", &s);spfa(s);ll sum = 0;for (int i = 1; i <= n; i++)if (pre[i])sum += val[pre[i]];cout << sum << endl;for (int i = 1; i <= n; i++)if (pre[i])printf("%d ", pre[i]);printf("\n");}return 0;}


0 0
原创粉丝点击