码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2513--Colored Sticks【字典树编号 && 并查集判连通 && 欧拉路】

时间:2015-07-30 23:27:19      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:

Colored Sticks
Time Limit: 5000MS   Memory Limit: 128000K
Total Submissions: 32351   Accepted: 8536

Description

You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color?

Input

Input is a sequence of lines, each line contains two words, separated by spaces, giving the colors of the endpoints of one stick. A word is a sequence of lowercase letters no longer than 10 characters. There is no more than 250000 sticks.

Output

If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.

Sample Input

blue red
red violet
cyan blue
blue magenta
magenta cyan

Sample Output

Possible

无向图存在欧拉路的充要条件为:

①     图是连通的;

②     所有节点的度为偶数,或者有且只有两个度为奇数的节点。


这里用了两种方法,一种是直接分配好内存,用时:985MS

#include <cstdio>
#include <cstring>
#include <iostream>
#define maxn 500500
using namespace std;

struct node {
    int id;
    node *next[30];
};
node *root;
node tree[maxn * 10];//先分配好内存。

int du[maxn], per[maxn], color;//color 编号
int ans = 0;

node *create(){
    node *p = &tree[ans++];
    for(int i = 0 ; i < 26; ++i)
        p -> next[i] = NULL;
    return p;
};

void insert (char *s, int id){
    node *p = root;
    for(int i = 0; s[i]; ++i){
        int k = s[i] - 'a';
        if(p -> next[k] == NULL)
            p -> next[k] = create();
        p = p ->next[k];
    }
    p -> id = id;
}

int search (char *s){
    node *p = root;
    for(int i = 0; s[i]; ++i){
        int k = s[i] - 'a';
        if(p -> next[k] == NULL)
            return 0;
        p = p -> next[k];
    }
    return p->id;
}

void init(){
    for(int i = 1; i <= maxn; ++i)
        per[i] = i;
    memset(du, 0 ,sizeof(du));
    color = 0;
}

int find(int x){
    int r = x;
    while( r != per[r])
        r = per[r];
    per[x] = r;
    return r;
}

void join (int x, int y){
    int fx = find(x);
    int fy = find(y);
    per[fx] = fy;
}

bool judge(){
	int sum = 0; 
    for(int  i = 1; i <= color; ++i)
        if(du[i] % 2 == 1)  sum++;
    if(sum != 0 && sum != 2)    return false;
    int k = find(1);
    for(int  i = 2; i <= color; ++i)
        if(k != find(i))
            return false;
    return true;
}

int main (){
    char s1[15], s2[15];
    init();
    root = create();
    while(cin >> s1 >> s2){
        int x = search(s1);
        int y = search(s2);
        if(!x) insert(s1,x = ++color);
        if(!y) insert(s2,y = ++color);
        du[x]++, du[y]++;
        join(x, y);
    }
    if(judge())
        printf("Possible\n");
    else
        printf("Impossible\n");

    return 0;
}

第二种,动态分配内存,用时久一点:1860MS

#include <cstdio>
#include <cstring>
#include <iostream>
#define maxn 500500
using namespace std;

struct node {
    int id;//纪录颜色的编号 
    node *next[30];
};
node *root;
//node tree[maxn * 10];//先分配好内存。

int du[maxn], per[maxn], color;

//int ans = 0;
//node *create(){
//    node *p = &tree[ans++];
//    for(int i = 0 ; i < 26; ++i)
//        p -> next[i] = NULL;
//    return p;
//};

void insert (char *s, int id){
    node *p = root;
    for(int i = 0; s[i]; ++i){
        int k = s[i] - 'a';
        if(p -> next[k] == NULL){
        	node *q = new node;
        	memset(q -> next,NULL,sizeof(q -> next));
        	p -> next[k]= q;
		} 
        p = p ->next[k];
    }
    p -> id = id;
}

int search (char *s){
    node *p = root;
    for(int i = 0; s[i]; ++i){
        int k = s[i] - 'a';
        if(p -> next[k] == NULL)
            return 0;
        p = p -> next[k];
    }
    return p->id;
}

void init(){
    for(int i = 1; i <= maxn; ++i)
        per[i] = i;
    memset(du, 0 ,sizeof(du));
    color = 0;
}

void initroot(){
	root = new node;
	memset(root -> next, NULL, sizeof(root->next)); 
} 
int find(int x){
    int r = x;
    while( r != per[r])
        r = per[r];
    per[x] = r;
    return r;
}

void join (int x, int y){
    int fx = find(x);
    int fy = find(y);
    per[fx] = fy;
}

bool judge(){
	int sum = 0; 
    for(int  i = 1; i <= color; ++i)
        if(du[i] % 2 == 1)  sum++;
    if(sum != 0 && sum != 2)    return false;
    int k = find(1);
    for(int  i = 2; i <= color; ++i)
        if(k != find(i))
            return false;
    return true;
}

int main (){
    char s1[15], s2[15];
    init();
    initroot();
    //root = create();
    while(cin >> s1 >> s2){
        int x = search(s1);
        int y = search(s2);
        if(!x) insert(s1,x = ++color);
        if(!y) insert(s2,y = ++color);
        du[x]++, du[y]++;
        join(x, y);
    }
    if(judge())
        printf("Possible\n");
    else
        printf("Impossible\n");

    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 2513--Colored Sticks【字典树编号 && 并查集判连通 && 欧拉路】

标签:

原文地址:http://blog.csdn.net/hpuhjh/article/details/47156573

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!