BZOJ 1050并查集+贪心

1050: [HAOI2006]旅行comf

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3333  Solved: 1851
[Submit][Status][Discuss]

Description

给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T,求

一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出这个

比值,如果需要,表示成一个既约分数。 备注: 两个顶点之间可能有多条路径。

Input

第一行包含两个正整数,N和M。下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向公路

,车辆必须以速度v在该公路上行驶。最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比

最小的路径。s和t不可能相同。

1<N<=500,1<=x,y<=N,0<v<30000,0<M<=5000

Output

如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。

如果需要,输出一个既约分数。

Sample Input

【样例输入1】

4 2

1 2 1

3 4 2

1 4

【样例输入2】

3 3

1 2 10

1 2 5

2 3 8

1 3

【样例输入3】

3 2

1 2 2

2 3 4

1 3

Sample Output

【样例输出1】

IMPOSSIBLE

【样例输出2】

5/4

【样例输出3】

2

每次看题解都会感觉题解好无赖好强   http://hzwer.com/844.html

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gcd(int a,int b) {return !b?a:gcd(b,a%b);}
struct node{
   int u,v,w;
   bool operator <(const node &B)const {
   return w<B.w;
   }
}e[30008];
int f[508];
int findx(int x) {return x==f[x]?f[x]:f[x]=findx(f[x]);}
int main(){
    int S,T;
    int n,m;
    int ansm=-1,ansz=-1;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;++i) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    scanf("%d%d",&S,&T);
    int st=0;
    sort(e,e+m);
    while(st<m){
        int mx=-1,mi=-1;
        for(int i=1;i<=n;++i) f[i]=i;
        int x=st;
        for(;x<m;++x){
            int u=findx(e[x].u),v=findx(e[x].v),w=e[x].w;
            f[u]=v;
            if(findx(S)==findx(T)) {
                mx=w;
                break;
            }
        }
        if(mx==-1) {
            if(ansm==-1) {puts("IMPOSSIBLE");return 0;}
            else break;
        }
        for(int i=1;i<=n;++i) f[i]=i;
        for(;x>=0;--x) {
            int u=findx(e[x].u),v=findx(e[x].v),w=e[x].w;
            f[u]=v;
            if(findx(S)==findx(T)) {
                mi=w;
                break;
            }
        }
        st=x+1;
        int tt=gcd(mi,mx);
        mi/=tt;
        mx/=tt;
        if(ansm==-1||ansm*mi>ansz*mx) {
            ansm=mx;
            ansz=mi;
        }
    }
    if(ansz==1) printf("%d\n",ansm);
    else printf("%d/%d",ansm,ansz);
}

时间: 2024-11-07 18:26:21

BZOJ 1050并查集+贪心的相关文章

HDU 1051 并查集+贪心

Wooden Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 11694    Accepted Submission(s): 4837 Problem Description There is a pile of n wooden sticks. The length and weight of each stick ar

zoj 3659 Conquer a New Region 并查集+贪心

点击打开链接题目链接 Conquer a New Region Time Limit: 5 Seconds      Memory Limit: 32768 KB The wheel of the history rolling forward, our king conquered a new region in a distant continent. There are N towns (numbered from 1 to N) in this region connected by s

POJ 1456 Supermarket 区间问题并查集||贪心

F - Supermarket Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1456 Appoint description:  System Crawler  (2015-11-30) Description A supermarket has a set Prod of products on sale. It earns a p

Vijos 1776 关押罪犯 【并查集+贪心】

题目: S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多.如果两名怨气值为c的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c的冲突事件.每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到S城Z市长那里.公务繁忙的Z市长只会去看列表中的第一

并查集+贪心 HDU4424

先对边进行从大到小的排序 并查集保存节点数和长度 Conquer a New Region Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1289    Accepted Submission(s): 429 Problem Description The wheel of the history rolling forward, o

bzoj 1171 并查集优化顺序枚举 | 线段树套单调队列

详见vfleaking在discuss里的题解. 收获: 当我们要顺序枚举一个序列,并且跳过某些元素,那么我们可以用并查集将要跳过的元素合并到一起,这样当一长串元素需要跳过时,可以O(1)跳过. 暴力: 1 /************************************************************** 2 Problem: 1171 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:1908 ms 7

poj 1456 Supermarket - 并查集 - 贪心

题目传送门 传送点I 传送点II 题目大意 有$n$个商品可以销售.每个商品销售会获得一个利润,但也有一个时间限制.每个商品需要1天的时间销售,一天也只能销售一件商品.问最大获利. 考虑将出售每个物品尽量外后安排.这样当一个商品不能安排的时候看能不能替换掉它能够出售的时间中盈利最小的商品. 因此可以将物品排序,这样只用考虑能否让每个物品出售. 为了找到第一个空闲时间,又因为已经安排的时间不会改变,所以用并查集将已经安排了出售的时间段缩起来. Code 1 /** 2 * poj 3 * Prob

BZOJ 1015 并查集+离线倒序

统计块个数写错了调了好久啊,BZOJ1696的弱化版本. 1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 #include <map> 6 #define fi first 7 #define se second 8 #define mp make_pair 9 #define pa pair<int,int>

Codeforces 437D The Child and Zoo(贪心+并查集)

题目链接:Codeforces 437D The Child and Zoo 题目大意:小孩子去参观动物园,动物园分很多个区,每个区有若干种动物,拥有的动物种数作为该区的权值.然后有m条路,每条路的权值为该条路连接的两个区中权值较小的一个.如果两个区没有直接连接,那么f值即为从一个区走到另一个区中所经过的路中权值最小的值做为权值.问,平均两个区之间移动的权值为多少. 解题思路:并查集+贪心.将所有的边按照权值排序,从最大的开始连接,每次连接时计算的次数为连接两块的节点数的积(乘法原理). #in