您的位置:首页 > 其它

POJ 2513Colored Sticks 并查集,字典树

2011-12-15 08:13 381 查看
本题综合性很强,用并查集是必须要用路劲压缩查找,其实可以用DFS来判断图的联通性,但肯定没并查集的效率高。字典树我用的是全局变量申请,但要开足够大的空间,开500000RUN ERROR一次,结果开500000*10就A的,而且时间只有 600MS ,字典树也可以动态创建,但时间肯定要多花的,时间空间自己去取舍吧..

#include <iostream>

using namespace std;

#define  ST_COUNT  500000
struct TNode
{
int parent;
int data;
}sn[ST_COUNT];

struct TrieNode
{
int data;
int child[26];
}trNode[ST_COUNT*10]; // 字典树节点要开多一点
int tr_index = 1;

int g_NodeId = 0; // 给每一个节点的唯一编号
int NodeDegree[ST_COUNT]; // 存放节点的度

int CreateTrieNode(int inData)
{
memset(trNode[tr_index].child, 255, sizeof(trNode[tr_index].child) );
trNode[tr_index].data = inData;
tr_index++;
return tr_index-1;
}

int FindAddInsertTrie(char szStr[], int szLen) // 查询字典树,并插入新的节点
{
int trBase = 0, re, tdata;
int i;
for(i = 0; i < szLen; i++)
{
if( trNode[trBase].child[szStr[i] - 'a'] == -1 )
{
if( szLen-i-1 == 0 ) tdata = g_NodeId++;
else tdata = -1;
re = CreateTrieNode(tdata);
trNode[trBase].child[szStr[i] - 'a'] = re;
trBase = re;
}
else
{
trBase = trNode[trBase].child[szStr[i] - 'a'];
}
}

return trNode[trBase].data;
}

int findPEx(int inf) // 路径压缩查找
{
return sn[inf].parent == -1 ? inf : sn[inf].parent = findPEx(sn[inf].parent);
}

int findP(int inf)
{
int tf;
if( sn[inf].parent == -1 )
{
return inf;
}
else
{
tf = findP(sn[inf].parent);
sn[inf].parent = tf;
return tf;
}
}
int main()
{
// 61088K  594MS
freopen("in.txt", "r", stdin);

int i, j, ta, tb, fa, fb;
char sza[12], szb[12];
// 计算节点的度
// 判断图的联通性
memset(trNode[0].child, 255, sizeof(trNode[0].child) );
trNode[0].data = -1;
memset(NodeDegree, 0, sizeof(NodeDegree) );
for(i = 0; i < ST_COUNT; i++) sn[i].parent = -1;

while( scanf("%s", sza) != EOF )
{
scanf("%s/n", szb);
ta = FindAddInsertTrie(sza, strlen(sza) ); // 查找字典树,并插入
tb = FindAddInsertTrie(szb, strlen(szb) );

NodeDegree[ta]++; // 计算节点的度
NodeDegree[tb]++;

fa = findPEx(ta); // 查找集合
fb = findPEx(tb);
if( fa != fb ) // 合并
{
sn[fa].parent = fb;
}
}

int odd = 0;
bool IsLink = true, IsO = true;
int only = findPEx(0);
for(i = 1; i < g_NodeId; i++) // 判断图的联通性
{
if( only != findPEx(i) )
{
IsLink = false;
break;
}
}

if( IsLink )
{
for(i = 0; i < g_NodeId; i++) // 判断欧拉路
{
if( NodeDegree[i]%2 != 0 ) odd++;
if( odd > 2 ) break;
}
if( odd > 2 )
cout<<"Impossible"<<endl;
else
cout<<"Possible"<<endl;
}
else
cout<<"Impossible"<<endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: