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;
}

 

posted @ 2018-11-01 11:22  wrjlinkkkkkk  阅读(130)  评论(0编辑  收藏  举报