POJ 1679 次小生成树 Kruskal +DFS优化
来源:互联网 发布:数据化决策 编辑:程序博客网 时间:2024/06/16 08:32
http://poj.org/problem?id=1679
看了网上大部分都是直接多次跑 kruskal的,数据大了会耗时间。先深搜一次跑出最小生成树各点路径的最大边权,存在MAXCST[I][J]表示i——》J的路径最大的边的边权
然后逐一减去这个边加上不是最小生成树的边再取最小值便是次小生成树了
#include<iostream>#include<vector>#include<algorithm>using namespace std;int father[105];//父亲节点数组bool used[10005];//标记边是否处于最小生成树内int cost[105][105];//记录最小生成树2点的花费int maxcost[105][105];//存最小生成树任意2点的最大路径bool mark[105];//最小生成树标记vector<int> vis;//记录哪些点在最小生成树内int ans;//最小生成树的权值之和int n, m;bool hash1[105];struct node{ int from, to, w;};bool cmp(node &a,node &b){ if (a.w<b.w) return true; return false;}node edug[10005];vector<int> shu[105];void init(){ memset(mark, false, sizeof(mark)); memset(used, false, sizeof(used)); memset(maxcost, -1, sizeof(maxcost)); memset(cost, -1, sizeof(cost)); for (int i = 0; i <= n; i++) { father[i] = i; } ans = 0; vis.clear();}int find(int x){ if (father[x] == x) return x; return father[x] = find(father[x]);}bool combine(int x,int y,int w,int i){ int fx = find(x); int fy = find(y); if (fx != fy) { used[i] = true; father[fy] = fx; shu[x].push_back(y);//建立最小生成树的领接表,这里是无向变 shu[y].push_back(x); ans+=cost[x][y] = cost[y][x] = w;//统计和记录最小生成树2点花费 if (!mark[x])//记录哪些点在最小生成树内 { mark[x] = true; vis.push_back(x); } if (!mark[y]) { mark[y] = true; vis.push_back(y); } return true; } return false;}void dfs(int f, int t, int w, int root)//深搜处理最小树的任意2点的最大路径{ if (hash1[f])//找过了 return; hash1[f] = true; for (int i = 0; i < shu[f].size(); i++) { if (shu[f][i] == t) continue; maxcost[root][shu[f][i]] = maxcost[shu[f][i]][root] = max(w, cost[f][shu[f][i]]);//以前走过的路径和当前路径的权取最大值 dfs(shu[f][i], f, max(w, cost[f][shu[f][i]]), root); }}int krusal(){ int num = 0; sort(edug,edug + m,cmp); for (int i = 0; i < m; i++) { if (combine(edug[i].from, edug[i].to, edug[i].w, i)) num++; if (num == n - 1) break; } for (int i = 0; i < vis.size(); i++) { memset(hash1, false, sizeof(hash1)); dfs(vis[i], -1, 0, vis[i]); } int sum = 0x3f3f3f3f; for (int i = 0; i < m; i++) { if (used[i]) continue; int u = edug[i].from; int v = edug[i].to; int w = edug[i].w; sum = min(ans + w - maxcost[u][v],sum);//逐一减去这个边加上不是最小生成树的边再取最小值便是次小生成树了 } if (sum == ans) cout << "Not Unique!" << endl; else cout << ans << endl; return 0;}int main(){ int t; cin >> t; while (t--) { cin >> n >> m; init(); for (int i = 0; i < m; i++) { cin >> edug[i].from >> edug[i].to >> edug[i].w; } krusal(); }}
0 0
- POJ 1679 次小生成树 Kruskal +DFS优化
- POJ 1679 The Unique MST(次小生成树&Kruskal)
- poj 1679__The Unique MST(次小生成树,kruskal)
- POJ 1679 The Unique MST (次小生成树Prime/Kruskal)
- poj 1679次小生成树的两种解法: Prim和Kruskal
- POJ 1679:The Unique MST(次小生成树&&Kruskal)
- [次小生成树] Prime Kruskal
- poj1679(次小生成树,kruskal)
- 次小生成树模板(kruskal)
- 次小生成树的Kruskal实现
- 次小生成树 prim和kruskal
- POJ 1679 次小生成树
- poj 1679 最小 次小生成树
- 次小生成树 (poj 1679)
- POJ 1679 次小生成树
- 次小生成树 POJ 1679
- 次小生成树POJ 1679
- poj 1679 次小生成树
- POJ 1787 Charlie's Change 最多金币
- AtomicInteger
- 行为型模式-责任链模式
- [笔记]遗传算法 genetic algorithm
- UVa 10622 - Perfect P-th Powers(对数+快速幂)
- POJ 1679 次小生成树 Kruskal +DFS优化
- iOS开发 - SDWebImage使用(一个可管理远程图片加载的类库)
- hdu 1091 A+B for Input-Output Practice (III)
- Android Studio创建项目
- iOS支付宝问题之:调用支付宝AlipaySDK找不到头文件<openssl/rsa.h>
- 下载文件的php代码
- jsp页面加时间戳问题
- 配置Tomcat使用https协议(配置SSL协议)
- HDU 3746