BZOJ 1050 [HAOI2006]旅行comf(并查集)
题意:
求无向图中从s到t路径上权值最大比最小的值最小的路径,输出这个值
思路:
满足这样一种关系的路径一定在权值连续的边集里!
我们只需要对权值排序,然后枚举区间求最值即可。
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<stack> #include<queue> #include<deque> #include<set> #include<vector> #include<map> #include<functional> #define fst first #define sc second #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lc root<<1 #define rc root<<1|1 #define lowbit(x) ((x)&(-x)) using namespace std; typedef double db; typedef long double ldb; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> PI; typedef pair<ll,ll> PLL; const db eps = 1e-6; const int mod = 1e9+7; const int maxn = 8e5+100; const int maxm = 2e6+100; const int inf = 0x3f3f3f3f; const db pi = acos(-1.0); struct Edge{ int x,y; int w; }edge[50000 + 10]; bool cmp(Edge a, Edge b){ return a.w < b.w; } int fa[50000 +10]; int tol; void addedge(){ int x, y, w; scanf("%d %d %d", &x, &y, &w); if(x==y)return; edge[tol].x=x; edge[tol].y=y; edge[tol++].w=w; return; } int l, r; int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]); } int gcd(int a, int b){ return b==0?a:gcd(b,a%b); } int main() { int n, m; int s, t; double ans = 30000.0 + 1.0; tol = 1; l = -1; scanf("%d %d", &n, &m); for(int i = 1; i <= m; i++){ addedge(); } scanf("%d %d", &s, &t); sort(edge+1, edge+1+m,cmp); for(int i = 1; i <= m; i++){ for(int j = 1; j <= n; j++)fa[j]=j; for(int j = i; j <= m; j++){ int t1 = find(edge[j].x); int t2 = find(edge[j].y); if(t1!=t2){ fa[t1]=t2; } if(find(s)==find(t)){ double tmp = (double)1.0*edge[j].w/(edge[i].w+0.0); if(tmp < ans){ ans = tmp; l = i; r = j; } break; } } } if(l==-1){ printf("IMPOSSIBLE\n"); return 0; } l = edge[l].w; r = edge[r].w; int g = gcd(r,l); l/=g;r/=g; if(l&&r%l!=0)printf("%d/%d\n",r,l); else printf("%d",r/l); return 0; }