luogu1955 [NOI2015] 程序自动分析
题目大意
假设x1,x2,x3...代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。i,j<=1000000000, n<=1000000
思路
如果把所有相等的变量纳为一个或几个集合,那么输出yes当且仅当同一个相等集合中不存在一对xi,xj被要求不相等。集合→并查集。i,j,n的范围→离散化。
离散化的标准做法
功能
将离散的数据压缩到一个有限的区间处理。具体可以为输入一个数的下标,输出该下标的排名。
实现
将原始下标排序,得到一个下标为原始下标排名顺序、值为原始下标的数组。然后我们就可以运用LowerBound二分由原始下标找到其在原数组中的位置了。
注意事项
并查集
- 一开始所有节点的Father都是自己。
- Join两个节点是将一个节点的Root的Father设为另一个节点的Root,而不是将节点的Father设为另一个节点。
整体
- 如果只想得到70分的话,注意下标范围是多于N的,所以并查集中的N都应当设为1000000。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
using namespace std; const int MAX_N = 200010; struct Discret
{
private:
int SortedA[MAX_N];
int Rank[MAX_N];
int N; int LowerBound(int *a, int l, int r, int k)
{
while (l < r)
{
int mid = (l + r) / 2;
if (k <= SortedA[mid])
r = mid;
else
l = mid + 1;
}
return l;
} public:
void Init(int n, int *a)
{
N = n;
for (int i = 1; i <= n; i++)
SortedA[i] = a[i];
sort(SortedA + 1, SortedA + n + 1); int prevVal = 0, rankCnt = 0;
for (int i = 1; i <= n; i++)
{
if (SortedA[i] != prevVal)
{
Rank[i] = ++rankCnt;
prevVal = SortedA[i];
}
else
Rank[i] = rankCnt;
}
} int GetRank(int val)
{
return Rank[LowerBound(SortedA, 1, N, val)];
} }List; struct UnionFind
{
private:
struct Node
{
Node *Father;
}_nodes[MAX_N]; Node *GetRoot(Node *cur)
{
return cur->Father == cur ? cur : cur->Father = GetRoot(cur->Father);
} public:
void Init(int n)
{
for (int i = 1; i <= n; i++)
_nodes[i].Father = _nodes + i;
} bool SameRoot(int a, int b)
{
Node *root1 = GetRoot(_nodes + a);
Node *root2 = GetRoot(_nodes + b);
return root1 == root2;
} void Join(int a, int b)
{
GetRoot(_nodes + a)->Father = GetRoot(_nodes + b);
}
}G; int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
static vector< pair<int, int> > equal, nequal;
static int OrgVal[MAX_N];
int caseCnt;
scanf("%d", &caseCnt);
while (caseCnt--)
{
equal.clear();
nequal.clear(); int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
int x1, x2, isEqual;
scanf("%d%d%d", &x1, &x2, &isEqual); if (isEqual)
equal.push_back(pair<int, int>(x1, x2));
else
nequal.push_back(pair<int, int>(x1, x2)); OrgVal[i * 2 - 1] = x1;
OrgVal[i * 2] = x2;
}
List.Init(n * 2, OrgVal);
G.Init(n * 2);
for (int i = 0; i < equal.size(); i++)
{
int rank1 = List.GetRank(equal[i].first), rank2 = List.GetRank(equal[i].second);
if (!G.SameRoot(rank1, rank2))
G.Join(rank1, rank2);
} bool Ok = true;
for (int i = 0; i<nequal.size(); i++)
{
int rank1 = List.GetRank(nequal[i].first), rank2 = List.GetRank(nequal[i].second);
if (G.SameRoot(rank1, rank2))
{
Ok = false;
break;
}
}
if (Ok)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
luogu1955 [NOI2015] 程序自动分析的更多相关文章
- codevs4600 [NOI2015]程序自动分析==洛谷P1955 程序自动分析
4600 [NOI2015]程序自动分析 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 在实现 ...
- Codevs 4600 [NOI2015]程序自动分析
4600 [NOI2015]程序自动分析 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 传送门 题目描述 Description 在实现程序自动分析的过程中,常常需 ...
- BZOJ4195 [Noi2015]程序自动分析(离散化+并查集)
4195: [Noi2015]程序自动分析 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 689 Solved: 296 [Submit][Sta ...
- BZOJ4195 NOI2015 程序自动分析
4195: [Noi2015]程序自动分析 Time Limit: 10 Sec Memory Limit: 512 MB Description 在实现程序自动分析的过程中,常常需要判定一些约束条件 ...
- 【BZOJ4195】[Noi2015]程序自动分析 并查集
[BZOJ4195][Noi2015]程序自动分析 Description 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3 ...
- bzoj 4195: [Noi2015]程序自动分析
4195: [Noi2015]程序自动分析 Description 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3,…代表 ...
- [UOJ#127][BZOJ4195][NOI2015]程序自动分析
[UOJ#127][BZOJ4195][NOI2015]程序自动分析 试题描述 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2, ...
- [NOI2015]程序自动分析(并查集,离散化)
[NOI2015]程序自动分析 Description 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3,-代表程序中出现的 ...
- [NOI2015]程序自动分析(并查集)
题目描述 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3...代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变 ...
随机推荐
- 每日算法——新型在线LCA
在线LCA一般大家都会用倍增吧,时间复杂度O(nlogn),空间复杂度O(nlogn),都是非常严格的复杂度限制,并且各种边界处理比较麻烦,有没有更快更好的办法呢? 我们发现,在树链剖分时,我们不经意 ...
- struts2OGNL表达式(三)
OGNL表达式 OGNL对象试图导航语言.${user.addr.name}这种写法就叫对象试图导航.Struts框架使用OGNL作为默认的表达式语言 OGNL不仅仅可以试图导航,支持比EL表达式更加 ...
- 使用CMD建立指定格式的文件
一.建立空文件的几种方法1.cd.>a.txtcd.表示改变当前目录为当前目录,即等于没改变:而且此命令不会有输出.>表示把命令输出写入到文件.后面跟着a.txt,就表示写入到a.txt. ...
- for 循环练习题
X3 * 6528 = 3X * 8256X为一个数字 填入一个数字 使等式成立 for (var x=1;x<=9&&x>0;x++) { if ((x*10+3)*65 ...
- C++泛型 && Java泛型实现机制
C++泛型 C++泛型跟虚函数的运行时多态机制不同,泛型支持的静态多态,当类型信息可得的时候,利用编译期多态能够获得最大的效率和灵活性.当具体的类型信息不可得,就必须诉诸运行期多态了,即虚函数支持的 ...
- spring3+quartz2
听说来自这里www.ydyrx.com 转载的: 最近公司要用定时任务,自己想着学习并完成任务,百度,google,360,必应,能用的搜索都用了,参差不齐,搞了一整天,也没找到一个好的例子.没办法, ...
- BZOJ 1827: [Usaco2010 Mar]gather 奶牛大集会 树形DP + 带权重心
Description Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来举办这次集会.每个奶牛居住在 N(1<=N<=100,0 ...
- 【剑指Offer】42、和为S的两个数字
题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输出描述: 对应每个测试案例,输出两个数, ...
- Skyline Web 端数据浏览性能优化
三维数据的效率一直是个瓶颈,特别是在Web端浏览一直是个问题,在IE内存限制1G的条件下,对于三维数据动不动几十G的数据量,这1G显得多么微不足道.虽然现在三维平台都是分级加载,或者在程序中采用数据分 ...
- UNIX C 进程Part2
1.获取进程ID #include <unistd.h> pid_t getpid(void); //获取子进程id pid_t getppid(void);//获取父进程id 2.获取实 ...