hdu2860 并查集模拟

判断条件有点坑

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<string>
  6 #include<queue>
  7 #include<algorithm>
  8 #include<map>
  9 #include<iomanip>
 10 #include<climits>
 11 #define INF 1e11
 12 #define MAXN 100010
 13 using namespace std;
 14
 15 #define _min(a,b) (((a)<(b))?((a):(b)))
 16 //适用于正负整数
 17 template <class T>
 18 inline bool scan_d(T &ret) {
 19     char c; int sgn;
 20     if (c = getchar(), c == EOF) return 0; //EOF
 21     while (c != ‘-‘ && (c<‘0‘ || c>‘9‘)) c = getchar();
 22     sgn = (c == ‘-‘) ? -1 : 1;
 23     ret = (c == ‘-‘) ? 0 : (c - ‘0‘);
 24     while (c = getchar(), c >= ‘0‘&&c <= ‘9‘) ret = ret * 10 + (c - ‘0‘);
 25     ret *= sgn;
 26     return 1;
 27 }
 28 typedef long long LL;
 29
 30 struct soldier{
 31     int rate, com;
 32 }s[MAXN];
 33 struct Com{
 34     LL low;
 35     int num;
 36     Com(){
 37         low = INF;
 38         num = 0;
 39     }
 40 }c[MAXN];
 41 int fa[MAXN];
 42 int n, m, k;
 43 int x, y;
 44 string o;
 45
 46
 47 int find(int x)
 48 {
 49     if (fa[x]  == x) return x;
 50     return fa[x] = find(fa[x]);
 51 }
 52
 53 void init()
 54 {
 55     for (int i = 0; i < MAXN; ++i)
 56         fa[i] = i,c[i].low = INF,c[i].num = 0;
 57 }
 58
 59 bool merge(int a,int b)
 60 {
 61     int x = find(a);
 62     int y = find(b);
 63     if (x == y) return true;
 64     else if (x != y) {
 65         if (c[x].low > c[y].low) c[x].low = c[y].low;
 66         c[x].num += c[y].num;
 67         fa[y] = x;
 68     }
 69     return false;
 70 }
 71 int main()
 72 {
 73     //n companies, k soldiers  m orders
 74     while (cin >> n >> k >> m) {
 75         init();
 76         for (int i = 0; i < k; ++i) {
 77             scan_d(s[i].rate);
 78             scan_d(s[i].com);
 79             c[s[i].com].num++;
 80             if (c[s[i].com].low > s[i].rate)
 81             c[s[i].com].low = s[i].rate;
 82         }
 83         for (int i = 0; i < m; ++i) {
 84             cin >> o;
 85             if (o == "GT"){
 86                 scan_d(x);
 87                 if (find(x) == x && c[x].num != 0) printf("Lowest rate: %I64d.\n",c[x].low);
 88                 else if (find(x) == x && c[x].num == 0) printf("Company %d is empty.\n", x);
 89                 else printf("Company %d is a part of company %d.\n",x,fa[x]);
 90             }
 91             else if (o == "MG") {
 92                 scan_d(x);  scan_d(y);
 93                 if (x != find(x) || y != find(y) || merge(x,y)) puts("Reject");
 94                 else puts("Accept");
 95             }
 96             else if (o == "AP") {
 97                 scan_d(x);  scan_d(y);
 98                 if (y != find(y)) {
 99                     puts("Reject");
100                     continue;
101                 }
102                 if (c[y].low > x) c[y].low = x;
103                 c[y].num++;
104                 puts("Accept");
105             }
106         }
107         puts("");
108     }
109     return 0;
110 }
时间: 2024-10-03 13:46:24

hdu2860 并查集模拟的相关文章

棋盘上的守卫 并查集模拟外向基环树

棋盘上的守卫 基环树就是n个点n条边的树,每个点的入度为1就是外向基环树因为这样的话这个图是往外扩张的,反之内向. 然后这个树自然就只且只有一个环. 题意:n行m列,要求选n个守卫守卫n个行,m个守卫守卫m个列,守卫不能重复,且每个守卫只能守卫行或列,每个守卫一个价值,求最小的代价. 思路:将关于点的图转化为关于边的图,构造一个图含有n+m个点表示n行和m列,题目给的图上的每个点的价值就可以代表点到点的边权了,可以想到如果要覆盖所有的点,就是满足条件的方案,这样的话这个图就是一个每个点都是入度为

【并查集】【模拟】Codeforces 699D Fix a Tree

题目链接: http://codeforces.com/problemset/problem/699/D 题目大意: 通过给定当前节点的父亲给你一棵有错的树,可能有多个根和环,输出改成正确的一棵树至少要修改几个节点的父亲和修改后所有点的父亲值 题目思路: [并查集][模拟] 用并查集把成环的归在一起(类似强连通分量),然后统计分量数并修改. 第一个出现的当作根,其余的每一块连通分量都去掉一条边改为连接到根上. 1 // 2 //by coolxxx 3 ////<bits/stdc++.h>

HDU 2860 (模拟+并查集)

Regroup Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1057    Accepted Submission(s): 297 Problem Description When ALPC42 got to a panzer brigade, He was asked to build software to help them r

HDU 4775 Infinite Go(并查集,模拟)

HDU 4775 Infinite Go 题目链接 题意:围棋,两人轮流走,如果有一链被围死,就会被吃掉,问下完后最后黑色和白色各剩多少棋 思路:模拟,利用一个并查集来保存链,然后并记录下周围有多少个空格,然后去模拟,注意几个点,就是删除的时候,要把空格还回去,还有边界的位置是也算被围死的 代码: #include <stdio.h> #include <string.h> #include <queue> #include <map> using name

区间 (模拟并查集优化)

问题描述 给出一个序列 a1, ..., an. 定义一个区间 [l,r] 是好的,当且仅当这个区间中存在一个 i,使得 ai 恰好等于 al, al+1, ..., ar-1, ar 的最大公因数. 求最长的好的区间的长度. 输入 第一行 n,表示序列的长度; 第二行 n 个数 a1,a2,...,an. 输出 输出一行一个数,表示最长的好的区间的长度. 题解 题解写代码里可能容易懂? 代码 #include <cstdio> #define ll long long #define fil

【NOIP模拟_54测试】【并查集】【二进制】【搜索】【区间序列类】

第一题 Mushroom的序列 大意: 给一个序列,求一段连续最长区间满足:最多改变一个数,使得区间是严格的上升子序列. 解: 直接扫描一遍,记一个最长上升子序列编号.然后从每一个编号为1 的点来判断是否可以将两个序列合并,有两种情况,讨论需要注意多种子情况...我可能想的比较复杂,所以第一遍写的时候少考虑了一些相等的情况,就WA 了一个点. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #i

[CSP-S模拟测试]:Dash Speed(线段树+并查集+LCA)

题目描述 比特山是比特镇的飙车圣地.在比特山上一共有$n$个广场,编号依次为$1$到$n$,这些广场之间通过$n−1$条双向车道直接或间接地连接在一起,形成了一棵树的结构. 因为每条车道的修建时间以及建筑材料都不尽相同,所以可以用两个数字$l_i,r_i$量化地表示一条车道的承受区间,只有当汽车以不小于$l_i$且不大于$r_i$的速度经过这条车道时,才不会对路面造成伤害. $Byteasar$最近新买了一辆跑车,他想在比特山飙一次车.$Byteasar$计划选择两个不同的点$S,T$,然后在它

codevs 1078最小生成树 Kruskal+并查集

题目描述 Description 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助. 约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场.为了使花费最少,他想铺设最短的光纤去连接所有的农场. 你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案. 每两个农场间的距离不会超过100000 输入描述 Input Description 第一行: 农场的个数,N(3<=N<=100).

POJ 2492 (简单并查集) A Bug&#39;s Life

题意:有编号为1~n的虫子,开始假设这种昆虫是异性恋.然后已知xi 和 yi进行交配,根据已知情况分析能否推理出其中是否有同性恋 这道题和 POJ 1182 食物链 十分相似,不过在更新与父节点关系的时候要简单一些 sex数组保存的是与父节点的性别关系,如果与父节点是同性,则为0,否则是1 每次路径压缩的同时要更新sex[a] = (sex[a] + sex[temp]) % 2; 还有就是如果x 和 y 不在一个集合,两棵树进行合并的时候,考虑x px y py 四者之间的关系,有 paren