bzoj1050 并查集乱搞

impossible打错。。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define rep(i,l,r) for(int i=l;i<r;i++)
 6 #define clr(a,x) memset(a,x,sizeof(a))
 7 using namespace std;
 8 struct edge{
 9     int q,z,v;
10     void read(){
11         scanf("%d%d%d",&q,&z,&v);
12     }
13     bool operator<(const edge &e)const{
14         return v<e.v;
15     }
16 };
17 const int maxn=505,maxm=5005,inf=0x7fffffff;
18 edge e[maxm];
19 int n,m,fa[maxn],mx[maxn],mn[maxn];
20 int find(int a)
21 {
22     return fa[a]==a?a:fa[a]=find(fa[a]);
23 }
24 int gcd(int a,int b)
25 {
26     return b==0?a:gcd(b,a%b);
27 }
28 int main()
29 {
30     cin>>n>>m;
31     rep(i,0,m) e[i].read();
32     int s,t,ansmax=-1,ansmin=-1;
33     cin>>s>>t;
34     sort(e,e+m);
35     rep(i,0,m){
36         rep(j,1,n+1) fa[j]=j;
37         int mx,mn=e[i].v;
38         rep(j,i,m){
39             int a=find(e[j].q),b=find(e[j].z);
40             if(a!=b){
41                 mx=e[j].v;
42                 fa[a]=b;
43             }
44             if(find(s)==find(t)){
45                 if(ansmax==-1||mx*1.0/mn<ansmax*1.0/ansmin)
46                 {
47                     ansmax=mx;
48                     ansmin=mn;
49                 }
50                 break;
51             }
52         }
53     }
54     if(ansmax==-1) printf("IMPOSSIBLE");
55     else{
56         int gc=gcd(ansmax,ansmin);
57         if(gc==ansmin) printf("%d",ansmax/ansmin);
58         else printf("%d/%d",ansmax/gc,ansmin/gc);
59     }
60     return 0;
61 }

1050: [HAOI2006]旅行comf

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1809  Solved: 924
[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不可能相同。

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

HINT

【数据范围】

1<  N < = 500

1 < = x, y < = N,0 < v < 30000,x ≠ y

0 < M < =5000

Source

[Submit][Status][Discuss]

时间: 2024-11-10 15:17:45

bzoj1050 并查集乱搞的相关文章

并查集乱搞 bzoj1015

建图建错4次 改了2个钟...这本是道水题... 1 program hehe; 2 type 3 edge=record 4 q,z,next:longint; 5 end; 6 var 7 n,m,q,i,j,k,cnt:longint; 8 p,pd:array[0..500000] of boolean; 9 e:array[0..500000] of edge; 10 ans,c,first,f,d:array[0..500000] of longint; 11 12 function

Codeforces Round #286 div.1 D 506D D. Mr. Kitayuta&#39;s Colorful Graph【并查集】

题目链接:http://codeforces.com/problemset/problem/506/D 题目大意: 给出n个顶点,m条边,每条边上有一个数字,代表某个颜色.不同数字代表不同的颜色.有很多个询问,每个询问问有多少条纯种颜色的路径使得某两个点联通. 分析: 这个题一看就想用并查集来搞,每种颜色用一个并查集处理.对于输入的每条边,我们只需要将这两个点在这条边的颜色对应的并查集中合并就好了.查询的时候,我们只需要检测这两个点在多少个颜色对应的并查集中是在统一集合中的,那么就有多少条纯种颜

[BZOJ1594] [Usaco2008 Jan]猜数游戏(二分 + 并查集)

传送门 题中重要信息,每堆草的数量都不一样. 可以思考一下,什么情况下才会出现矛盾. 1.如果两个区间的最小值一样,但是这两个区间没有交集,那么就出现矛盾. 2.如果两个区间的最小值一样,并且这两个区间有交集,那么这个最小值一定在交集中,但是如果这个交集被某个最小值较大的区间,或是一些最小值较大的区间的并集包含,那么也是矛盾的. 可以二分答案,将这些区间按照最小值从大到小排序,然后可以用线段树维护,也可以用并查集来搞. 下面是用并查集来搞的. 每到一个区间,可以将[l,r]中的f变成r+1,如果

并查集总结篇

1.模板题poj1611the suspects 每个组内的人,同一个组内都是感染者,问与"0"号人有关的有多少人 #include <iostream> #include<cstdio> using namespace std; const int MAXN = 1000100; struct DS { int f[MAXN]; void init(int n) { for(int i=0;i<n;i++) f[i]=i; } int ff(int x)

「UVA 11987」Almost Union-Find 「带权并查集」「思维」

你发现,这个第二个操作不可能用普通并查集来搞,很棘手 但是你考虑一下,并查集维护的是个森林结构,并且路径压缩的时候每个森林的根是不会变的, 也就是意味着每删掉一个点你需要让他的踪影消失匿迹即可,并不需要让他在原有的树结构上消失. 具体怎么消失?把贡献全在根上减掉即可,再新建一个新点连进去. 这个新点可以用id数组表示,即id[x]为x节点现在的编号. #include <bits/stdc++.h> #define test(...) fprintf(stderr, __VA_ARGS__)

【BZOJ-4668】冷战 并查集 + 启发式合并 + 乱搞

4668: 冷战 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 37  Solved: 24[Submit][Status][Discuss] Description 1946 年 3 月 5 日,英国前首相温斯顿·丘吉尔在美国富尔顿发表“铁幕演说”,正式拉开了冷战序幕. 美国和苏联同为世界上的“超级大国”,为了争夺世界霸权,两国及其盟国展开了数十年的斗争.在这段时期,虽然分歧和冲突严重,但双方都尽力避免世界范围的大规模战争(第三次世界大战)爆发

学渣乱搞系列之Tarjan模板合集

学渣乱搞系列之Tarjan模板合集 by 狂徒归来 一.求强连通子图 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <climits> 7 #include <vector> 8 #include <queue> 9 #incl

快速搞定并查集算法

目录 算法介绍 wiki 通俗解释 算法实现(C语言) 算法实战 算法介绍 wiki 并查集 通俗解释 零基础学并查集算法 算法实现(C语言) Find函数(未采用路径压缩) int Find(int x) { int r = x; while(pre[r] != r) { r = pre[r]; } return r; } Find函数(路径压缩递归实现) int Find(int x) { if(pre[x] == x) return x; else { pre[x] = Find(pre[

【BZOJ-3673&amp;3674】可持久化并查集 可持久化线段树 + 并查集

3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status][Discuss] Description n个集合 m个操作操作:1 a b 合并a,b所在集合2 k 回到第k次操作之后的状态(查询算作操作)3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0<n,m<=2*10^4 Input Output Sample Input 5 6