题目:codevs1001
思路:看了好多题解才会的,然后发现其实是我不会并查集,恶补了一下并查集;先把所有路按权值从大到小排序,然后依次枚举,假如想知道的景点之间有直达的路,肯定输出1无疑。
题解:Code_Together的博客;
并查集:并查集(Union-Find)算法介绍 - 优快云博客;并查集 - CYJB - 博客园。
代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct node
{
int b,e;
double w;
}p[5005];
int fn[505];
int fz = 1<<30,fm = 1;
bool cmp(node x,node y)
{
return x.w>y.w;
}
int find(int x)
{
return x == fn[x]?x:fn[x] = find(fn[x]);
}
int main()
{
int n,m;
int begin, end;
cin >> n >> m;
for(int i = 0;i < m;i++)
{
cin >> p[i].b >> p[i].e >> p[i].w;
}
sort(p,p+m,cmp);
cin >> begin >> end;
bool flag = false;
for(int i = 0;i < m;i++)
{
if(p[i].b == begin&&p[i].e == end)
{
cout << "1";
return 0;
}
for(int j = 0;j < n;j++)
{
fn[j] = j;
}
for(int k = i;k < m;k++)
{
int x = find(p[k].b);
int y = find(p[k].e);
if(x!=y) fn[y] = x;
if(find(begin) == find(end)&&i!=k)
{
if(p[i].w/p[k].w < (double)fz/fm)
{
fm = p[k].w;
fz = p[i].w;
flag = true;
}
break;
}
}
}
if(!flag) cout << "IMPOSSIBLE";
else if(fz%fm == 0) cout << fz/fm;
else{
int x = __gcd(fm,fz);
cout << fz/x << "/" << fm/x;
}
return 0;
}