Time Limit: 5000MS | Memory Limit: 128000K | |
Total Submissions: 28302 | Accepted: 7481 |
Description
Input
Output
Sample Input
blue red red violet cyan blue blue magenta magenta cyan
Sample Output
Possible
Hint
Source
非常沮喪的 RE 多次。
trie樹用鏈表來實現吧:
結構體中的 next指針用來尋找下一個字母node。
isdict變量表示這個結點是不是一個詞典中的單詞。(必須有!)
struct node {
node * next[26];
bool isdict;
};
然後遍歷輸入串,在樹上行走。發現NULL指針就new一個。一定要注意new後要把新結點的next指針都初始化爲NULL。否則可能是野指針,導致RE。
while(s[i]) {
int a = s[i] - 'a';
assert(a < 26);
if (cur->next[a] == NULL) {
cur->next[a] = new node;
memset(cur->next[a]->next, NULL, sizeof(cur->next[a]->next));
cur->next[a]->f = false;
}
cur = cur->next[a];
i++;
}
首先要判斷圖的聯通(用並查集後,所有點的root相同)
其次要判斷入度爲奇數的點,或者爲0,或者爲2。
以上兩個條件都滿足時,則必存在歐拉回路,否則必不存在歐拉回路。
提交記錄:
1-N、RE。 記得要初始化指針。否則結果不可預知。
N+1、AC。
/*Source Code
Problem: 2513 User: 775700879
Memory: 87916K Time: 1391MS
Language: G++ Result: Accepted
Source Code*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define oo 0x3f3f3f3f
#define N 1000000
using namespace std;
int icount[N];
int par[N];
int rank[N];
int color_num = 0;
struct node {
bool f;
int num;
struct node * next[30];
};
node * head = new node;
int find(int a) {
int x = par[a];
if (x == a) return x;
else return par[a] = find(x);
}
void unite(int a, int b) {
int x = find(a);
int y = find(b);
if (x == y) return ;
if (rank[x] < rank[y]) {
par[x] = y;
}
else {
par[y] = x;
if (rank[x] == rank[y]) rank[x] ++;
}
}
int find_num(char s[]) {
int i = 0;
node * cur = head;
while(s[i]) {
int a = s[i] - 'a';
assert(a < 26);
if (cur->next[a] == NULL) {
cur->next[a] = new node;
memset(cur->next[a]->next, NULL, sizeof(cur->next[a]->next));
cur->next[a]->f = false;
}
cur = cur->next[a];
i++;
}
if (cur->f == false) {
cur->f = true;
cur->num = color_num++;
}
return cur->num;
}
int main() {
char a[30], b[30];
int i, j, k;
int numa, numb;
for (i = 0; i < N; i++) {par[i] = i; rank[i] = 0;}
memset(head->next, NULL, sizeof(head->next));
while (EOF != scanf("%s%s", a, b)) {
numa = find_num(a);
numb = find_num(b);
assert(numa < N);
assert(numb < N);
icount[numa]++;
icount[numb]++;
unite(numa, numb);
}
bool flag = true;
int num = 0;
if (color_num >= N) return 0;
for (i = 0; i < color_num; i++) {
if (icount[i] % 2 != 0) num++;
if (num > 2) {
flag = false;
break;
}
}
if (num == 1) flag = false;
if (flag) {
int root = par[0];
for (i = 0; i < color_num; i++) {
if (par[i] != root) {
flag = false;
break;
}
}
}
if (flag) printf("Possible\n");
else printf("Impossible\n");
return 0;
}