您的位置:首页 > 其它

Poj 2513 Colored Sticks//Trie+并查集+欧拉通路

2013-07-17 14:18 302 查看
  这道题可以直接看出是用欧拉通路来做,但是数据特别大,只能想办法压缩数据。所以用Trie树来储存几万种颜色,并给这些颜色标记为相应的结点。

  下面是代码:

#include<stdio.h>
#include<string.h>
#define maxn 510000

int ch[maxn][26];
int val[maxn];
int degree[maxn];
int f[maxn];
int cnt;
int ID;
char s1[11],s2[11];

void initi()
{
for(int i = 0; i < maxn; i++) f[i] = i;
memset(ch[0],0,sizeof(ch[0]));
ID = 0;
cnt = 1;
}

int find_father(int x)
{
if(x != f[x])
{
f[x] = find_father(f[x]);
}
return f[x];
}

void union_node(int x,int y)
{
x = find_father(x);
y = find_father(y);
if(x != y) f[x] = y;
}

void insert_Trie(char *s)
{
int u = 0;
while(*s)
{
int id = *s - 'a';
if(ch[u][id] == 0)
{
memset(ch[cnt],0,sizeof(ch[cnt]));
val[cnt] = -1;
ch[u][id] = cnt++;
}
u = ch[u][id];
s++;
}
val[u] = ID;
}
int get_id(char *s)
{
int u = 0;
while(*s)
{
int id = *s - 'a';
if(ch[u][id] == 0) return -1;
u = ch[u][id];
s++;
}
if(val[u] >= 0) return val[u];
return -1;
}

void solve()
{
bool ok = true;
int i;
for(i = 0; !degree[i]; i++);
for(int j = i + 1; j < ID; j++)
{
if(degree[j] && find_father(j) != find_father(i))
{
ok = false;
break;
}
}
int flag = 0;
if(ok)
{
for(int j = 0; j < ID; j++)
{
if(degree[j] %2 != 0) flag++;
if(flag > 2)
{
ok = false;
break;
}
}
}
if(ok && (flag == 2 || flag == 0) ) printf("Possible\n");
else printf("Impossible\n");
}

int main()
{
initi();
while(scanf("%s %s",s1,s2) == 2)
{
int u = get_id(s1);
int v = get_id(s2);
if(u == - 1) insert_Trie(s1),u = ID++;
if(v == -1) insert_Trie(s2),v = ID++;
union_node(u,v);
degree[u]++;
degree[v]++;
}
solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息