HDU 6005 Pandaland[最小生成树][LCA]
来源:互联网 发布:贝斯谱的软件 编辑:程序博客网 时间:2024/06/06 00:26
题意:给定
分析:通过观察可以发现,最短的环除去一条边外一定是在这个图的最小生成树上。
这样,我们可以通过枚举不在树上的边,求树上这条边的两点间距离,加上边的权值并取个最小值即可。
需要注意的是,题目给你的图可能有多个联通块。
以下是代码。
#include<bits/stdc++.h>using namespace std;#define ll long long#define ull unsigned long long#define lson l,mid,id<<1#define rson mid+1,r,id<<1|1typedef pair<int, int> pii;typedef pair<ll, ll> pll;const int INF = 0x3f3f3f3f;const ll LINF = 0x3f3f3f3f3f3f3f3f;const int MAXN = 10010;const int MAXM = 100005;const ll MOD = 998244353;const int maxn = 205 + 100;const double eps = 1e-8;const double PI = acos(-1.0);map<pii, int>mp;int tot;int pre[10005];int f[MAXN][20];int dep[MAXN];int val[MAXN];bool vis[MAXN];bool ss[MAXN];struct edge { int u, v, cost; edge(int _u = 0, int _v = 0, int _cost = 0) :u(_u), v(_v), cost(_cost) {} bool operator<(const edge &a) { return cost < a.cost; }};struct to { int v, cost; to(int _v = 0, int _cost = 0) :v(_v), cost(_cost) {}};vector<to>vec[MAXN];vector<edge>v;int find(int x) { return x == pre[x] ? x : pre[x] = find(pre[x]); }void mix(int x, int y) { int fx = find(x), fy = find(y); if (fx != fy) { pre[fx] = fy; }}void kruskal() { sort(v.begin(), v.end()); for (int i = 1; i <= tot; ++i)pre[i] = i; for (int i = 0; i < v.size(); ++i) { int posu = find(v[i].u), posv = find(v[i].v); if (posu != posv) { vis[i] = 1; mix(posu, posv); vec[v[i].u].push_back(to(v[i].v, v[i].cost)); vec[v[i].v].push_back(to(v[i].u, v[i].cost)); } }}void dfs(int u, int pre,int now,int cur) { ss[u] = 1; val[u] = now; dep[u] = cur; f[u][0] = pre; for (int i = 0; i < vec[u].size(); ++i) { int vv = vec[u][i].v; if (vv == pre)continue; dfs(vv, u, now + vec[u][i].cost, cur + 1); }}void getst() { for (int i = 1; i < 20; ++i) { for (int j = 1; j <= tot; ++j) { f[j][i] = f[f[j][i - 1]][i - 1]; } }}int getLca(int x, int y) { if (dep[x]<dep[y]) swap(x, y); for (int i = 19; i >= 0; i--){ if (dep[y] <= dep[f[x][i]]){ x = f[x][i]; } } if (x == y) return x; for (int i = 19; i >= 0; i--){ if (f[x][i] != f[y][i]){ x = f[x][i]; y = f[y][i]; } } return f[x][0];}void init() { memset(ss, 0, sizeof(ss)); memset(f, 0, sizeof(f)); memset(vis, 0, sizeof(vis)); v.clear(); tot = 0; mp.clear();}int main() { int m, T, cas = 0, a, b, c, d, e; scanf("%d", &T); while (T--) { init(); scanf("%d", &m); for (int i = 0; i < m; ++i) { scanf("%d%d%d%d%d", &a, &b, &c, &d, &e); if (mp.count(pii(a, b)) == 0)mp[pii(a, b)] = ++tot; if (mp.count(pii(c, d)) == 0)mp[pii(c, d)] = ++tot; v.push_back(edge(mp[pii(a, b)], mp[pii(c, d)], e)); } for (int i = 1; i <= tot; ++i)vec[i].clear(); kruskal(); for(int i=1;i<=tot;++i)if(!ss[i])dfs(i, 0, 0, 1); getst(); int res = INF; for (int i = 0; i < v.size(); ++i) { if (!vis[i]) { int lca = getLca(v[i].u, v[i].v); res = min(res, val[v[i].u] + val[v[i].v] - 2 * val[lca] + v[i].cost); } } if (res == INF)printf("Case #%d: 0\n", ++cas); else printf("Case #%d: %d\n", ++cas, res); }}
阅读全文
0 0
- HDU 6005 Pandaland[最小生成树][LCA]
- HDU 6005 Pandaland 最小环(最小生成树+LCA)
- HDU 6005 Pandaland
- hdu 6005 Pandaland(dij+暴力)
- 最小生成树+LCA+uva11354
- <最小生成树><lca>Heatwave
- Pandaland HDU
- Pandaland HDU
- HDU 6005 Pandaland(dijkstra + 剪枝)
- HDU 6005 Pandaland——dijkstra + 剪枝
- 【最小环 && 离散化】HDU 6005 Pandaland
- 【BZOJ3732】Network 最小生成树+LCA
- 【bzoj3732】 network 最小生成树+lca
- UVA 11354 LCA+最小生成树
- 过路费(最小生成树+lca)
- [最小生成树] [LCA] [BZOJ4242] 水壶(bottle)
- [BZOJ]3732: Network 最小生成树 LCA
- 【BZOJ】Network 最小生成树+LCA
- HDU1078
- Android浏览器— —书签\历史
- 《算-入》第二章
- HTTP头域列表与解释 之 request篇
- 51 nod 1424
- HDU 6005 Pandaland[最小生成树][LCA]
- Struts2 的国际化实现
- 复杂链表的复制
- HTTP头域列表与解释 之 response篇
- 洛谷2672 推销员
- C++:iostream中包含一个叫time的东西
- 欢迎使用CSDN-markdown编辑器官方使用教程
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B.Coin(数学推公式)
- 使用nginx+tomcat搭建一个简单负载均衡