zoukankan      html  css  js  c++  java
  • 【Luogu P2502】[HAOI2006]旅行

    题目大意:

    给定一个有 (n) 个点的无向图,求出从 (s)(t) 的最短路上的最大权值与最小权值的比。

    正文:

    并查集查询 (s)(t) 是否连通,可以通过给邻接表按权值从大到小排序,枚举每次连通的最大最小权值比即可。

    代码:

    int find_(int x) {if(x == fa[x])return x;return fa[x] = find_(fa[x]);}
    
    void Add(int u, int v, int w)
    {
    	e[++tot] = (node){u, v, head[u], w}, head[u] = tot;
    }
    
    bool cmp(node a, node b)
    {
    	return a.w > b.w;
    }
    
    int gcd(int a, int b)
    {
    	if(b == 0) return a;
    	return gcd(b, a%b);
    }
    
    int main()
    {
    	scanf ("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++) fa[i] = i;
    	for (int i = 1; i <= m; i++)
    	{
    		int u, v, w;
    		scanf("%d%d%d", &u, &v, &w);
    		Add(u, v, w);
    		fa[find_(u)] = find_(v);
    	}
    	scanf ("%d%d", &s, &t);
    	if(find_(s) != find_(t))
    	{
    		puts("IMPOSSIBLE");
    		return 0;
    	}
    	sort (e + 1, e + 1 + tot, 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 u = e[j].from, v = e[j].to;
    			fa[find_(u)] = find_(v);
    			if(find_(s) == find_(t))
    			{
    				double opt = e[i].w * 1.0 / e[j].w * 1.0;
    				if(opt < ans) 
    					maxsp = e[i].w, minsp = e[j].w, ans = opt;
    				break;
    			}
    		}
    	}
    	if(maxsp % minsp) printf("%d/%d", maxsp / gcd(maxsp, minsp), minsp / gcd(maxsp, minsp));
    	else printf("%d", maxsp / minsp);
    	return 0;
    }
    
    
    
  • 相关阅读:
    移动方法
    linux主编号的动态分配
    linux 分配和释放设备编号
    linux设备编号的内部表示
    linux主次编号
    linux模块参数
    linux scull 的设计
    linux模块加载竞争
    linux清理函数
    linux初始化中的错误处理
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/13353310.html
Copyright © 2011-2022 走看看