zoukankan      html  css  js  c++  java
  • HDU 1598 find the most comfortable road 并查集+贪心

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=1598

    find the most comfortable road

    Time Limit: 1000/1000 MS (Java/Others)
    Memory Limit: 32768/32768 K (Java/Others)
    #### 问题描述 > XX星有许多城市,城市之间通过一种奇怪的高速公路SARS(Super Air Roam Structure---超级空中漫游结构)进行交流,每条SARS都对行驶在上面的Flycar限制了固定的Speed,同时XX星人对 Flycar的“舒适度”有特殊要求,即乘坐过程中最高速度与最低速度的差越小乘坐越舒服 ,(理解为SARS的限速要求,flycar必须瞬间提速/降速,痛苦呀 ), > 但XX星人对时间却没那么多要求。要你找出一条城市间的最舒适的路径。(SARS是双向的)。 #### 输入 > 输入包括多个测试实例,每个实例包括: > 第一行有2个正整数n (1 接下来的行是三个正整数StartCity,EndCity,speed,表示从表面上看StartCity到EndCity,限速为speedSARS。speed<=1000000 > 然后是一个正整数Q(Q<11),表示寻路的个数。 > 接下来Q行每行有2个正整数Start,End, 表示寻路的起终点。 #### 输出 > 每个寻路要求打印一行,仅输出一个非负整数表示最佳路线的舒适度最高速与最低速的差。如果起点和终点不能到达,那么输出-1。 #### 样例 > **sample input** > 4 4 > 1 2 2 > 2 3 4 > 1 4 1 > 3 4 2 > 2 > 1 3 > 1 2 > > **sample output** > 1 > 0

    题解

    并查集+贪心。
    我们先对所有的边排序,然后对于每个查询,我们枚举开始的边,然后用并查集维护连通性,一旦目前的边足以连通查询的顶点对,那么说明这一轮的答案就出来了,像这样做m轮就能求出答案。最坏情况也就O(m^2)。

    代码

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #define X first
    #define Y second
    #define mp make_pair
    using namespace std;
    
    const int maxn = 1e3+10;
    const int INF = 0x3f3f3f3f;
    
    int n, m;
    
    int fa[maxn];
    
    int find(int x) { return fa[x] = fa[x] == x ? x : find(fa[x]); }
    
    struct Edge {
    	int u, v, w;
    	bool operator < (const Edge& tmp) const {
    		return w < tmp.w;
    	}
    }egs[maxn];
    
    int main() {
    	while (scanf("%d%d", &n, &m) == 2 && n) {
    		for (int i = 0; i < m; i++) {
    			scanf("%d%d%d", &egs[i].u, &egs[i].v, &egs[i].w);
    		}
    		sort(egs, egs + m);
    		int q;
    		scanf("%d", &q);
    		while (q--) {
    			int s, d;
    			scanf("%d%d", &s, &d);
    			int ans = INF;
    			for (int i = 0; i < m; i++) {
    				for (int i = 1; i <= n; i++) fa[i] = i;
    				for (int j = i; j < m; j++) {
    					Edge& e = egs[j];
    					int pu = find(e.u);
    					int pv = find(e.v);
    					if (pu != pv) {
    						fa[pv] = pu;
    					}
    					if (find(s) == find(d)) {
    						ans = min(ans, egs[j].w - egs[i].w);
    						break;
    					}
    				}
    			}
    			if (ans < INF) printf("%d
    ", ans);
    			else puts("-1");
    		}
    	}
    	return 0;
    }
    

    Notes

    很多枚举区间的问题,排序之类的预处理一下,一般只要枚举上界就可以了。

  • 相关阅读:
    December 23rd 2016 Week 52nd Friday
    December 22nd 2016 Week 52nd Thursday
    December 21st 2016 Week 52nd Wednesday
    December 20th 2016 Week 52nd Tuesday
    December 19th 2016 Week 52nd Sunday
    December 18th 2016 Week 52nd Sunday
    uva294(唯一分解定理)
    uva11624Fire!(bfs)
    fzu2150Fire Game(双起点bfs)
    poj3276Face The Right Way
  • 原文地址:https://www.cnblogs.com/fenice/p/5699758.html
Copyright © 2011-2022 走看看