Codeforces 545E【最小树形图】
2015-05-20 16:47
253 查看
/* I will wait for you */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <algorithm> #include <iostream> #include <fstream> #include <vector> #include <queue> #include <deque> #include <set> #include <map> #include <string> #define make make_pair #define fi first #define se second using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; typedef map<int, int> mii; const int maxn = 300010; const int maxm = 1010; const int maxs = 26; const int inf = 0x3f3f3f3f; const int P = 1000000007; const double error = 1e-9; inline ll read() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') f = (ch == '-' ? -1 : 1), ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * f; } struct edge { int u, v; ll w; int next, pos; } e[2 * maxn]; int n, m, s, cnt, head[maxn], vis[maxn], fa[maxn]; ll ans, dis[maxn]; void insert(int u, int v, ll w, int pos) { e[cnt] = (edge) {u, v, w, head[u], pos}, head[u] = cnt++; e[cnt] = (edge) {v, u, w, head[v], pos}, head[v] = cnt++; } void spfa() { for (int i = 1; i <= n; i++) dis[i] = (ll) inf * inf; queue<int> q; q.push(s), dis[s] = 0; while (!q.empty()) { int u = q.front(); q.pop(), vis[u] = 0; for (int i = head[u]; i != -1; i = e[i].next) { int v = e[i].v; if (dis[v] > dis[u] + e[i].w) { dis[v] = dis[u] + e[i].w; if (!vis[v]) vis[v] = 1, q.push(v); } } } } bool cmp(edge a, edge b) { ll disa = max(dis[a.u], dis[a.v]); ll disb = max(dis[b.u], dis[b.v]); return disa < disb || disa == disb && a.w < b.w; } int find(int u) { return u == fa[u] ? u : fa[u] = find(fa[u]); } vector<int> num; int main() { n = read(), m = read(); memset(head, -1, sizeof head); for (int i = 1; i <= m; i++) { int u = read(), v = read(); ll w = read(); insert(u, v, w, i); } s = read(), spfa(); sort(e, e + cnt, cmp); for (int i = 1; i <= n; i++) fa[i] = i; for (int i = 0; i < cnt; i++) { int u = e[i].u, v = e[i].v; if (abs(dis[u] - dis[v]) == e[i].w) { int fu = find(u), fv = find(v); if (fu != fv) { ans += e[i].w, fa[fu] = fv; num.push_back(e[i].pos); } } } printf("%I64d\n", ans); for (int i = 0; i < num.size(); i++) printf("%d ", num[i]); return 0; }
相关文章推荐
- CodeForces - 240E Road Repairs(最小树形图+输出路径)
- Codeforces 240E. Road Repairs 最小树形图+输出路径
- Codeforces 240E Road Repairs(最小树形图路径)
- Codeforces 240E. Road Repairs 最小树形图+输出路径
- Codeforces 240E. Road Repairs 最小树形图+输出路径
- 最小树形图(朱刘算法模板)
- 最小树形图
- poj 3398 Perfect Service(最小支配集树形DP)
- codeForces 472D 最小生成树
- codeforces 161D Distance in Tree 树形dp
- 最小树形图(朱刘算法)
- SPOJ 1479 +SPOJ 666 无向树最小点覆盖 ,第二题要方案数,树形dp
- pku 3164 Command Network(最小树形图)
- poj 3659 树形dp(树上的最小支配集)
- HDU 4003 Find Metal Mineral(树形dp,从根节点出发k个机器人遍历所有边的最小代价和)
- 【codeforces】gym 101137 K - Knights of the Old Republic【用最小生成树对图做集合dp】
- hdu5758 Explorer Bo 树形dp 最小链覆盖
- codeforces 337D 树形DP Book of Evil
- hdu4009 Transfer water(最小树形图模板)
- hdu 4081 最小生成树+树形dp