UVA 1395 Slim Span(kruskal算法)
2015-11-11 21:55
369 查看
题意:题目中要求求出,最苗条的生成树, 最苗条的生成树的定义是权值最大的边减去权值最小的边的权值差最小。
解题思路:
首先对读入的边进行排序,然后枚举最小的权值边。具体就是比当前枚举的边要小的边不会加入生成树。
注意两条边的情况, 和无边的情况。
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4141
解题思路:
首先对读入的边进行排序,然后枚举最小的权值边。具体就是比当前枚举的边要小的边不会加入生成树。
注意两条边的情况, 和无边的情况。
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4141
Memory: 0 KB | Time: 76 MS | |
Language: C++11 4.8.2 | Result: Accepted |
#include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<cctype> #include<list> #include<iostream> #include<map> #include<queue> #include<set> #include<stack> #include<vector> using namespace std; #define FOR(i, s, t) for(int i = (s) ; i <= (t) ; ++i) #define REP(i, n) for(int i = 0 ; i < (n) ; ++i) int buf[10]; inline long long read() { long long x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } inline void writenum(int i) { int p = 0; if(i == 0) p++; else while(i) { buf[p++] = i % 10; i /= 10; } for(int j = p - 1 ; j >= 0 ; --j) putchar('0' + buf[j]); } /**************************************************************/ #define MAX_N 110 const int INF = 0x3f3f3f3f; int parent[MAX_N]; int top = 0; int n; struct node { int u, v, w; }edge[MAX_N * MAX_N /2]; bool cmp(node a, node b) { return a.w < b.w; } int find(int a) { while(a != parent[a]) { a = parent[a]; } return a; } void unite(int a, int b) { int fa = find(a); int fb = find(b); if(fa == fb) return; parent[fb] = fa; } bool same(int a,int b) { return find(a) == find(b); } inline void add_edge(int u, int v, int w) { edge[top].u = u; edge[top].v = v; edge[top].w = w; top++; } inline void init(int n) { for(int i = 0 ; i <= n ; i++) { parent[i] = i; } } int kruskal(int cnt) { int all = 1; int res = -1; for(int i = cnt ; i < top ; i++) { int a = edge[i].u; int b = edge[i].v; if(!same(a, b) || n == 2) { unite(a, b); if(edge[i].w > res) { res = edge[i].w; } all++; } if(all >= n - 1) return res; } return INF; } int main() { while(~scanf("%d", &n) && n) { init(n); top = 0; int m = read(); int u, v, w; for(int i = 0 ; i < m ; i++) { u = read(); v = read(); w = read(); add_edge(u, v, w); } sort(edge, edge + top, cmp); int ans = INF; for(int i = 0 ; i < top ; i++) { unite(edge[i].u, edge[i].v); int ret = kruskal(i) - edge[i].w; if(ret < ans && ret >= 0) ans = ret; init(n); } if(ans > 100000) ans = -1; cout<<ans<<endl; } return 0; }
相关文章推荐
- Windows 10 Mobile 演示:系统输入法功能演示
- java.lang.NoClassDefFoundError: android.support.v4.view.ViewConfigurationCompat
- gazebo+ros搭建单目仿真环境:贴有二维码的天花板+kobuki+camera(2)
- android-csv-variants
- string去空格
- Angular js 随手记
- 在Unity中生成二维码
- 【算法竞赛练习题】三角螺旋阵
- 解决网络丢包问题及故障判断方法
- JDK数据类型Short、Long
- 《王爽——汇编语言》P206 实验室10第三个问题的答案
- Leetcode152: Gas Station
- 10 配置的详细说明
- 02.JMS基础
- 使用libsvm工具箱,README文档要仔细阅读
- Android之android.intent.category.LAUNCHER的用途和使用
- 09 JobManager 高可用安装(HA)
- muduo库阅读(36)——Net部分:事件循环线程池EventLoopThreadPool
- Gson简要使用笔记
- 2015-11-08 第三天