Title Source:http://poj.org/problem?id=2513
Title:
Give you N wooden sticks, each ends of each wooden stick are coated with color, and any two wooden sticks can be connected together. If they have the same color, ask you if you can finally connect all the wooden sticks into one one in one piece Essence
Question analysis:
This question is a judgment of the Euler channel, but it is tangled that the node is not an integer but a string, which is a headache = =
If you don’t know the Euler channel, you can Baidu yourself. Essence
Because the node is a string, we need to convert it into an integer node, which involves the search of the string, but Map will overtime at this question. Essence Essence So I think I can use AC automatic machine
code implementation:
#include <cStdio>
#include <cstring>
using namespace std;
TypeDef Char Char_T; // The type of character, if necessary, can be changed to int, etc.
const instal = 26; // The size of the character set
Const int Element_max = 5000100; // The most possible nodes in the trie graph are used for memory management
#Define Max 500010
int Father [max], rank [max];
int ID;
char s1 [max/2] [15], s2 [max/2] [15];
int d [max];
int degree [max];
BOOL VIS [MAX];
int Len1 [max/2], len2 [max/2];
Struct Triegraph
{{
Struct Trie
{{
BOOL MATCH;
int ID;
trie *pre, *child [sigma];
trie (): match (false), pre (0)
{{
MEMSET (Child, 0, SIZEOF (Child));
id = -1;
}
void * operator New (size_t, void * p)
{{
Return p;
}
} root, superroot;
static char storage [element_max*sizeof (trie)];
Static Trie* Data;
static void init ()
{{
data = (true*) storage;
}
void insert (char_t* s, int n) // Insert a string S in a trie
{{
// If you need to record some information in the Trie node, it is usually added to this function
true* t = & root;
For (int i = 0; i <n; ++ i)
{{
char_t c = s [i];
if (! T-> Child [C])
{{
t-> child [c] = new ((void*) data ++) trie;
if (i == n-1)
{{
ID ++;
}
}
t = t-> child [c];
}
if (! t-> match)
{{
t-> match = true;
t-> ID = ID;
}
}
Void build_graph () // After all the insertion is completed, the Trie tree is expanded into a figure
{{
static trie* q [element_max];
superroot.pre = root.pre = & superroot;
For (int i = 0; i <sigma; ++ i)
superroot.child [i] = & root;
int head = 0, tail = 0;
Q [tail ++] = & root;
While (Head! = Tail)
{{
trie* t = q [head ++];
T-> MATCH | = T-> Pre-> MATCH;
For (int i = 0; i <sigma; ++ i)
{{
if (t-> child [i])
{{
t-> child [i]-> Pre = T-> Pre-> Child [i];
Q [tail ++] = t-> child [i];
}
else
t-> child [i] = t-> pre-> child [i];
}
}
}
Int match (char_t* s, int n) // Whether the string that has been inserted into a string with a length n is matched
{{
true* t = & root;
For (int i = 0; i <n; ++ i)
{{
t = t-> child [s [i]];
}
Return T-> ID;
}
};
char triegraph :: storage [element_max*sizeof (trie)];
Triegraph :: Trie* Triegraph :: Data;
void make_set ()
{{
int i;
for (int i = 1; i <= max/2; i ++)
{{
rank [i] = 0;
father [i] = i;
}
}
int Find_Set (int X)
{{
if (x! = Father [x])
{{
father [x] = Find_Set (FATHER [X]);
}
Return father [x];
}
void union_set (int x, int y)
{{
x = Find_Set (x);
y = find_set (y);
if (rank [x]> rank [y])
father [y] = x;
else
{{
father [x] = y;
if (rank [x] == rank [y])
{{
rank [y] ++;
}
}
}
int Main ()
{{
Triegraph :: init ();
Triegraph g;
ID = 0;
int K = 0;
int cNT = 0;
MEMSET (Degree, 0, SIZEOF (DEGREE));
MEMSET (VIS, 0, SIZEOF (VIS));
make_set ();
While (Scanf (" %S %S", S1 [K], S2 [K])! = EOF)
{{
// Printf (" %s %s \ n", s1 [k], s2 [k]);
len1 [k] = strlen (s1 [k]);
For (int i = 0; i <Len1 [k]; ++ i)
s1 [k] [i]-= 'a';
g.insert (s1 [k], len1 [k]);
len2 [k] = strlen (s2 [k]);
For (int i = 0; i <Len2 [k]; ++ i)
s2 [k] [i]-= 'a';
g.insert (s2 [k], len2 [k]);
k ++;
}
g.build_graph ();
int ii = 0;
For (int i = 0; i <k; ++ i)
{{
// Printf (" %d %d \ n", len1 [i], len2 [i]);
int D1 = g.match (s1 [i], len1 [i]);
int d2 = g.match (s2 [i], len2 [i]);
if (! VIS [d1])
{{
d [ii ++] = d1;
vis [d1] = true;
}
if (! VIS [d2])
{{
d [ii ++] = d2;
vis [d2] = true;
}
degree [d1] ++;
degree [d2] ++;
union_set (d1, d2);
}
for (int i = 0; i <ii; i ++)
{{
if (degree [d [i]] % 2 == 1)
CNT ++;
}
MEMSET (VIS, FALSE, SIZEOF (VIS));
int ANS = 0;
if (cnt == 1 || cNT> = 3)
{{
Printf ("Impossible \ n");
}
else
{{
int Fanum = 0;
for (int i = 0; i <ii; i ++)
{{
int FA = Find_Set (d [i]);
// Printf (" %D %D \ n", d [i], FA);
if (! VIS [FA])
{{
vis [FA] = TRUE;
ANS ++;
}
}
if (ANS> 1)
Printf ("Impossible \ n");
else
Printf ("POSSIBLE \ n");
}
Return 0;
}