您的位置:首页 > 其它

欧拉路径 之 poj 2513 Colored Sticks

2016-01-04 16:42 337 查看
/*
欧拉路径 之 poj 2513 Colored Sticks

欧拉路径: 若图G中存在这样一条路径,使得它恰通过G中每条边一次,则称该路径为欧拉路径。

无向图存在欧拉路径 充要条件:
1) 图是连通的;
2) 所有节点的度为偶数,或者有且只有两个度为奇数的节点。

题目要求:
align the sticks in a straight line such that the colors of the endpoints that touch are of the same color.

模型转换:
木棒看作边,木棒两端看作节点(相同的颜色即为同一个节点),这样便可构成无向图G。
align the sticks in a straight line 即:在无向图G中,通过每条边一次。
即:判定无向图G是否存在欧拉路径

实现:
字典树 + 并查集

*/


#include <crtdbg.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include <cstddef>
#include <iterator>
#include <algorithm>
#include <string>
#include <locale>
#include <cmath>
#include <vector>
#include <cstring>
#include <map>
#include <utility>
#include <queue>
#include <stack>
#include <set>
#include <functional>
using namespace std;
typedef pair<int, int> PII;
typedef long long int64;
const int INF = 0x3f3f3f3f;
const int modPrime = 3046721;
const double eps = 1e-9;
const int MaxN = 500010;
const int MaxM = 10010;

int degree[MaxN];
int ftr[MaxN];
int rnk[MaxN];

//Union-Find Sets
void ufsIni()
{
for (int i = 0; i < MaxN; ++i)
{
ftr[i] = i;
rnk[i] = 0;
}
}
int ufsFind(int x)
{
if (x == ftr[x]) return x;
return ftr[x] = ufsFind(ftr[x]);
}
void ufsUnite(int x, int y)
{
x = ufsFind(x);
y = ufsFind(y);
if (x == y) return;

if (rnk[x] > rnk[y])
{
ftr[y] = x;
}
else
{
ftr[x] = y;
if (rnk[x] == rnk[y])
{
++rnk[y];
}
}
}

// Tree
struct Tree
{
Tree *next[26];
bool flag;
int num;
Tree()
{
flag = false;
memset(next, NULL, sizeof(next));
}
};

Tree *Root = new Tree;

int insertNode(string str, int num)
{
Tree *p = Root;
for (int i = 0; i < str.size(); ++i)
{
int pos = str[i] - 'a';
if (!(p->next[pos]))
{
p->next[pos] = new Tree;
}
p = p->next[pos];
}
if (!(p->flag))
{
p->flag = true;
p->num = num;
}
return p->num;
}

void destroyTree(Tree *root)
{
for (int i = 0; i < 26; ++i)
{
if (root->next[i])
{
destroyTree(root->next[i]);
}
}
delete[] root;
}

int main()
{
#ifdef HOME
freopen("in", "r", stdin);
//freopen("out", "w", stdout);
#endif

char str1[11], str2[11];
int num = 0;
fill(degree, degree + MaxN, 0);
ufsIni();
while (~scanf("%s %s", str1, str2))
{
int numTmp1 = insertNode(str1, num);
if (numTmp1 == num)
{
++num;
}
int numTmp2 = insertNode(str2, num);
if (numTmp2 == num)
{
++num;
}

++degree[numTmp1];
++degree[numTmp2];
ufsUnite(numTmp1, numTmp2);
}
destroyTree(Root);
for (int i = 1; i < num; ++i)
{
if (ftr[i] != ftr[0])
{
printf("Impossible\n");
return 0;
}
}
int oddCnt = 0;
for (int i = 0; i < num; ++i)
{
if (degree[i] & 1)
{
++oddCnt;
if (oddCnt >= 3)
{
break;
}
}
}
if (oddCnt == 0 || oddCnt == 2)
{
printf("Possible\n");
}
else
{
printf("Impossible\n");
}

#ifdef HOME
cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl;
_CrtDumpMemoryLeaks();
#endif
return 0;
}





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