题目大意

  假设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;
}

  

最新文章

  1. maven webapp栽坑录
  2. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(23)-设置角色遗留问题和为权限设置角色以及EasyUI Tabs的使用
  3. spring aop 声明式事务管理
  4. SQL NULL 值【摘自W3C】
  5. CSS实现完美垂直居中
  6. Mysql存储过程语法
  7. 软件光栅化渲染器Augustus计划
  8. 安装Composer 步骤
  9. centos 64位linux系统下安装appt命令
  10. css基本框架
  11. sklearn数据预处理-scale
  12. 如何将Excel转换成Markdown表格[转]
  13. Jenkins参数化构建(二)之 Maven command line使用Jenkins参数
  14. django 保存中文到mysql 报错django.db.utils.DatabaseError: Incorrect string value: &#39;\xE5\xBE\x88\xE7\x81\xB5
  15. 《JavaScript设计模式与开发》笔记 7.单例模式
  16. java web 大文件下载
  17. 在Asp.Net中使用jQueryEasyUI(转)
  18. netty--NioEventLoop滴干活
  19. 剑指offer——面试题32.1:分行从上到下打印二叉树
  20. MyBatis是支持普通 SQL查询

热门文章

  1. POJ 3630 trie树
  2. 2015 多校赛 第三场 1002 (hdu 5317)
  3. Phoenix与Squirrel 是什么?
  4. collectionView必须点击两次才跳转
  5. windows phone传感器
  6. Android MediaRecorder自定义分辨率
  7. dubbo之异步调用
  8. 使用GitGUI创建上传本地工程
  9. Arduino控制继电器模块
  10. (转)Bootstrap 之 Metronic 模板的学习之路 - (4)源码分析之脚本部分