poj 1733 并查集+偏移向…
2013-12-14 20:04
363 查看
题意: 题目给出一个有0、1组成的序列 , 长度为n 。 下面有m个条件 , 每个条件是:给出一个x到y的连续序列 ,
和这个序列中有偶数个1还是奇数个1 , 因为给出的条件可能有矛盾 , 所以要求出前多少个条件是没矛盾的。
这题有点意思 , 对于并查集的题目 , 首先要找到根节点 , 就是怎么来确定根节点 。
我们用:
0 : 表示偶数个1
1 : 表示奇数个1
我们用f[x-1] 表示0 到 x-1中1的个数是偶数还是奇数 , 如果 x 到 y有偶数个1 , 则 f[x-1]^f[y] =
0
反正有奇数个 , 则f[x-1]^f[y] = 1;
所以我们可以判断每个点和根的关系 , 来得到他们之间的关系 。
这题的偏移向量方程:
1、f[y] = abs(f[g]-f[h]+d);
根节点的偏移方程
2、f[x] = (f[x]+f[fa])%2; 子节点的偏移方程
代码:
#include
#include
#include
#include
using namespace std;
const int maxn = 50010*2;
int p[maxn] , f[maxn];
int n , m;
int find(int x)
{
if(p[x] ==
x) return x;
int fa =
p[x];
p[x] =
find(fa);
f[x] =
(f[x]+f[fa])%2;
return
p[x];
}
int main()
{
maphash;
map::iterator it;
while(scanf("%d" , &n) != EOF)
{
scanf("%d" ,
&m);
int i , j ,
x , y , k = 0;
int g ,
h;
char
cf[10];
int bz =
-1;
bool pre =
false;
memset(f , 0
, sizeof(f));
for(i = 0; i
<= 50010; i++)
p[i] = i;
for(i = 1; i
<= m; i++)
{
scanf("%d %d %s" , &x , &y , cf);
if(pre) continue;
g = h = -1;
it = hash.find(x-1);
if(it != hash.end())
g = it->second;
else hash[x-1] = k++ , g =
k-1;
it = hash.find(y);
if(it != hash.end())
h = it->second;
else hash[y] = k++ , h =
k-1;
x = find(g) , y = find(h);
if(cf[0] == 'e')
{
和这个序列中有偶数个1还是奇数个1 , 因为给出的条件可能有矛盾 , 所以要求出前多少个条件是没矛盾的。
这题有点意思 , 对于并查集的题目 , 首先要找到根节点 , 就是怎么来确定根节点 。
我们用:
0 : 表示偶数个1
1 : 表示奇数个1
我们用f[x-1] 表示0 到 x-1中1的个数是偶数还是奇数 , 如果 x 到 y有偶数个1 , 则 f[x-1]^f[y] =
0
反正有奇数个 , 则f[x-1]^f[y] = 1;
所以我们可以判断每个点和根的关系 , 来得到他们之间的关系 。
这题的偏移向量方程:
1、f[y] = abs(f[g]-f[h]+d);
根节点的偏移方程
2、f[x] = (f[x]+f[fa])%2; 子节点的偏移方程
代码:
#include
#include
#include
#include
using namespace std;
const int maxn = 50010*2;
int p[maxn] , f[maxn];
int n , m;
int find(int x)
{
if(p[x] ==
x) return x;
int fa =
p[x];
p[x] =
find(fa);
f[x] =
(f[x]+f[fa])%2;
return
p[x];
}
int main()
{
maphash;
map::iterator it;
while(scanf("%d" , &n) != EOF)
{
scanf("%d" ,
&m);
int i , j ,
x , y , k = 0;
int g ,
h;
char
cf[10];
int bz =
-1;
bool pre =
false;
memset(f , 0
, sizeof(f));
for(i = 0; i
<= 50010; i++)
p[i] = i;
for(i = 1; i
<= m; i++)
{
scanf("%d %d %s" , &x , &y , cf);
if(pre) continue;
g = h = -1;
it = hash.find(x-1);
if(it != hash.end())
g = it->second;
else hash[x-1] = k++ , g =
k-1;
it = hash.find(y);
if(it != hash.end())
h = it->second;
else hash[y] = k++ , h =
k-1;
x = find(g) , y = find(h);
if(cf[0] == 'e')
{
相关文章推荐
- poj 1182 并查集经典题…
- poj 1611 并查集训练
- poj 1703 并查集的拓展
- HDU 4277 USACO ORZ
- poj 1836 最长增长序列的变形
- 集合中子集的生成算法
- poj 1742
- LA 4726 Average
- 动态规划求 最长递增子序列
- 01背包和完全背包比较容易忽略的地…
- Distant Galaxy poj 3141
- unipue() 函数的功能
- poj 2015 Permutation Code
- poj 1088 经典的记忆化搜索
- 中位数的应用
- poj 1724
- poj1511(第一次用数组模拟邻接表…
- poj 2226
- poj2728最优比率生成树
- poj 1797