您的位置:首页 > 编程语言 > Go语言

POJ 1182并查集的经典运用

2013-10-01 20:18 295 查看


tag的取值:1表示x吃px,-1表示px吃x,0表示x与px同类

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

typedef struct {
int parent;
int tag;
}Node;

vector<Node> nodes;
int n, k;

void MakeSet()
{
nodes.resize( n+10 );
for(int i = 0; i < nodes.size(); ++i)
{
nodes[i].parent = i;
nodes[i].tag = 0;
}
}

int FindSet(int index, int& steps)
{
if( nodes[index].parent == index )
return index;
else
{
steps += nodes[index].tag;
nodes[index].parent = FindSet( nodes[index].parent, steps );
steps %= 3;
switch( steps )
{
case -2:
nodes[index].tag = 1;
break;
case 2:
nodes[index].tag = -1;
break;
default:
nodes[index].tag = steps;
}
return nodes[index].parent;
}
}

void Union(int r1, int r2, int t)
{
nodes[r2].parent = r1;
nodes[r2].tag = t;
}

int main()
{
cin >> n >> k;
MakeSet();
int ans = 0;
for(int i = 0; i < k; ++i)
{
int t, x, y;
cin >> t >> x >> y;
if( x > n || y > n )
++ans;
else if(t == 2 && x == y)
++ans;
else
{
int d1 = 0, d2 = 0;
int r1 = FindSet(x, d1);
int r2 = FindSet(y, d2);
if( r1 == r2 )
{
if(nodes[x].tag == nodes[y].tag && t != 1)
++ans;
if(t == 2)
{
int t1 = nodes[x].tag;
int t2 = nodes[y].tag;
if( (t1==-1&&t2==0)
|| (t1==-1&&t2==1)
|| (t1==1&&t2==-1) )
++ans;
}
}
else
{
int d = nodes[x].tag - 1 - nodes[y].tag;
if( d <= -2 )
d += 3;
else if( d >= 2 )
d -= 3;
Union(r1, r2, d);
}
}
}
cout << ans << endl;
return 0;
}


tag为-1,0,1时,代码写起来挺费劲的。借鉴了网上的代码,将tag的取值改为0,1,2;其中2表示px吃x,0,1取值含义保持不变

#include <iostream>
#include <vector>
#include <cstdio>

using namespace std;

class Node
{
public:
int parent;
int link;
int rank;
Node(int p=0, int l=0, int r=0):parent(p), link(l), rank(r){
};
};

vector<Node> nodes;
int n, k;

void MakeSet()
{
nodes.resize( n+1 );
for(int i = 1; i <= n; ++i)
nodes[i] = Node(i) ;
}

int FindSet(int i)
{
if( nodes[i].parent == i )
return i;
int p = nodes[i].parent;
nodes[i].parent = FindSet( nodes[i].parent );
nodes[i].link = (nodes[i].link + nodes[p].link)%3;
return nodes[i].parent;
}

void Union(int x, int y, int link)
{
int rx = FindSet(x);
int ry = FindSet(y);
if( nodes[rx].rank < nodes[ry].rank )
{
nodes[rx].parent = ry;
nodes[rx].link = (3 - nodes[x].link + link + nodes[y].link)%3;
}
else
{
nodes[ry].parent = rx;
if( nodes[rx].rank == nodes[ry].rank )
nodes[rx].rank += 1;
nodes[ry].link = (6 - nodes[y].link - link + nodes[x].link)%3;
}
}

int main()
{
int ans = 0;
scanf("%d%d", &n, &k);
MakeSet();
for(int i = 0; i < k; ++i)
{
int l, x, y;
scanf("%d%d%d", &l, &x, &y);
--l;
if(x > n || y > n)
++ans;
else if(l == 1 && x == y)
++ans;
else if( FindSet(x) == FindSet(y) )
{
if( (l+nodes[y].link)%3 != nodes[x].link )
++ans;
}
else
{
Union(x, y, l);
}
}
printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  POJ algorithm 算法