pku2513 Colored Sticks (hash+并查集+欧拉回路)
和pku1386 hdu1116 Play on Words差不多,不同的是这题的木棒是无向的,即是无向图。
可以hash也可以用字典树,个人喜欢hash,够快,不知道map会不会超时
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define MAXSIZE 500010//1313131
typedef struct node
{
int ind;
node *next;
} node;
node newnode[MAXSIZE];
typedef struct HashNode
{
node *first;
} HashNode;
HashNode hashtable[MAXSIZE]= {0};
int father[MAXSIZE];
int degree[MAXSIZE];
bool exist[MAXSIZE];
inline void init()
{
int i;
for(i=1; i<MAXSIZE+1; i++)
father[i]=-1;
}
int find_mfs(int x)
{
int i,t;
for(i=x; father[i]>0; i=father[i]) ;
while(x!=i)
{
t=father[x];
father[x]=i;
x=t;
}
return i;
}
inline void merge_mfs(int x,int y)
{
int fx=find_mfs(x),fy=find_mfs(y);
if(fx==fy) return;
father[y]=fx;
}
bool judge(bool *ex)
{
int i,f1=find_mfs(1);
for(i=1; i<MAXSIZE; i++)
if(ex[i])break;
f1=find_mfs(i++);
while(i<MAXSIZE)
{
if(ex[i] && find_mfs(i)!=f1)
return false;
i++;
}
return true;
}
unsigned int BKDRHash(char *str)
{
unsigned int seed = 131313; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0;
while (*str)
{
hash = hash * seed + (*str++);
}
return hash%MAXSIZE;
}
char words[MAXSIZE][11];
int main()
{
int i,j,x,index=1,newn=0;
while(scanf("%s %s",words[index],words[index+1])!=EOF)
{
x=BKDRHash(words[index]);
node *p=NULL;
for(p=hashtable[x].first; p && strcmp(words[p->ind],words[index])!=0 ; p=p->next) ;
if(p) i=p->ind;
else
{
p=&newnode[newn++];
i=p->ind=index;
p->next=hashtable[x].first;
hashtable[x].first=p;
}
x=BKDRHash(words[index+1]);
for(p=hashtable[x].first; p && strcmp(words[p->ind],words[index+1])!=0 ; p=p->next) ;
if(p) j=p->ind;
else
{
p=&newnode[newn++];
j=p->ind=index+1;
p->next=hashtable[x].first;
hashtable[x].first=p;
}
index+=2;
exist[i]=exist[j]=true;
degree[i]++;
degree[j]++;
merge_mfs(i,j);
}
int s=0;
for(i=1; i<MAXSIZE; i++)
if(exist[i])
{
if(degree[i]&1)
s++;
}
bool tag;
if(s<=2)
tag=judge(exist);
else
tag=false;
if(tag)
printf("Possible\n");
else
printf("Impossible\n");
return 0;
}
浙公网安备 33010602011771号