zoukankan      html  css  js  c++  java
  • BZOJ 1050 旅行comf 并查集+枚举下界

    题目链接:

    https://www.lydsy.com/JudgeOnline/problem.php?id=1050

    题目大意:

    给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T,求一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出这个比值,如果需要,表示成一个既约分数。 备注: 两个顶点之间可能有多条路径。

    思路:

    枚举最小的边,逐步按照权值从小到大将边加入并查集中,直到s-t连通为止。

    每次保留最小的ans(分数)即可。

      1 #include<bits/stdc++.h>
      2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
      3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时
      4 #define Min(a, b) ((a) < (b) ? (a) : (b))
      5 #define Mem(a) memset(a, 0, sizeof(a))
      6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
      7 #define MID(l, r) ((l) + ((r) - (l)) / 2)
      8 #define lson ((o)<<1)
      9 #define rson ((o)<<1|1)
     10 #define Accepted 0
     11 #pragma comment(linker, "/STACK:102400000,102400000")//栈外挂
     12 using namespace std;
     13 inline int read()
     14 {
     15     int x=0,f=1;char ch=getchar();
     16     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     17     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     18     return x*f;
     19 }
     20 
     21 typedef long long ll;
     22 const int maxn = 10000 + 10;
     23 const int MOD = 1000000007;//const引用更快,宏定义也更快
     24 const int INF = 1e9 + 7;
     25 const double eps = 1e-6;
     26 
     27 struct edge
     28 {
     29     int u, v, w;
     30     edge(){}
     31     edge(int u, int v, int w):u(u), v(v), w(w){}
     32     bool operator < (const edge& a)const
     33     {
     34         return w < a.w;
     35     }
     36 };
     37 vector<edge>e;
     38 int p[maxn];
     39 vector<int>G[maxn];
     40 void addedge(int u, int v, int w)
     41 {
     42     e.push_back(edge(u, v, w));
     43     G[u].push_back(e.size() - 1);
     44     e.push_back(edge(v, u, w));
     45     G[v].push_back(e.size() - 1);
     46 }
     47 int Find(int x)
     48 {
     49     return x == p[x] ? x : p[x] = Find(p[x]);
     50 }
     51 struct node
     52 {
     53     int a, b;
     54     node(){}
     55     node(int A, int B)
     56     {
     57         int g = __gcd(A, B);
     58         a = A / g, b = B / g;
     59     }
     60     bool operator < (const node& tmp)const
     61     {
     62         return a * tmp.b < b * tmp.a;
     63     }
     64 };
     65 
     66 int main()
     67 {
     68     int n, m, u, v, w, s, t;
     69     scanf("%d%d", &n, &m);
     70     while(m--)
     71     {
     72         scanf("%d%d%d", &u, &v, &w);
     73         addedge(u, v, w);
     74     }
     75     scanf("%d%d", &s, &t);
     76     sort(e.begin(), e.end());
     77     m = e.size();
     78     node ans(1, 0);//最大
     79     for(int start = 0; start < m; start++)//枚举下限
     80     {
     81         for(int i = 1; i <= n; i++)p[i] = i;//初始化并查集
     82         int cnt = -INF;
     83         for(int i = start; i < m; i++)
     84         {
     85             int u = e[i].u, v = e[i].v, w = e[i].w;
     86             u = Find(u);
     87             v = Find(v);
     88             p[u] = v;
     89             if(Find(s) == Find(t))
     90             {
     91                 cnt = w;
     92                 break;
     93             }
     94         }
     95         if(cnt == -INF)
     96         {
     97             break;
     98         }
     99         ans = min(ans, node(cnt, e[start].w));
    100     }
    101     if(ans.a == 1 && ans.b == 0)puts("IMPOSSIBLE
    ");
    102     else if(ans.b != 1)printf("%d/%d
    ", ans.a, ans.b);
    103     else printf("%d
    ", ans.a);
    104     return Accepted;
    105 }
  • 相关阅读:
    SQL——BETWEEN操作符
    SQL——IN操作符
    SQL——LIKE操作符
    SQL——ORDER BY关键字
    SQL——AND、OR运算符
    顺序执行
    流程控制
    集合类型
    字典类型
    字典 in 操作符
  • 原文地址:https://www.cnblogs.com/fzl194/p/9678507.html
Copyright © 2011-2022 走看看