舒适的路线

来源:互联网 发布:淘宝主播申请 编辑:程序博客网 时间:2024/04/28 09:39

思路就是并查集+枚举

把每条边按速度排序,从大到小枚举大的边,然后再枚举小的边,都并到一个集合中,如果发现起始点和终止点在一个集合中了,说明当前的边就是当前最大边中的最小边,然后用这个比值更新最终结果,不要忘记约分,而且如果最小边是最大边的因数的话也要特判。

还有就是浮点数的处理,把大边改成浮点型再比上小边,不然codevs只能对三个点

上码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;int n, m;int x, y;int pre[501];int high[501];struct line{int to;int from;int w;};line edge[5001];void init(){for (int i = 1;i <= n;i++){pre[i] = i;high[i] = 0;}}int find(int x){if (pre[x] == x)return x;else return pre[x] = find(pre[x]);}void unite(int x, int y){x = find(x);y = find(y);if (high[y] > high[x])pre[x] = y;else {pre[y] = x;if (high[x] == high[y])high[x]++;}}bool cmp(const line& a, const line& b){return a.w > b.w;}int gcd(int a, int b){if (b == 0)return a;else return gcd(b, a%b);}int main(){cin >> n >> m;int max1 = 9999999;int min1 = 1;for (int i = 1;i <= m;i++){cin >> edge[i].from >> edge[i].to >> edge[i].w;}cin >> x >> y;sort(edge + 1, edge + 1 + m,cmp);for (int i = 1;i <= m;i++){init();for (int j = i;j <= m;j++){unite(edge[j].from, edge[j].to);if (find(x) == find(y)){if (float(max1) / min1 > float(edge[i].w) / edge[j].w){max1 = edge[i].w;min1 = edge[j].w;}break;}}}int yue = gcd(max1, min1);if (max1 == 9999999 && min1 == 1)cout << "IMPOSSIBLE";else if (yue == 1)cout << max1 << "/" << min1;else if (yue == min1)cout << max1 / min1;else cout << max1 / yue << "/" << min1 / yue;return 0;}

原创粉丝点击