poj2513(trie树+欧拉路+并查集)

  题目的大意就是一根木棍两端涂上颜色,然后要把所有的木棍连成一根木棍,然后两根木棍能合并的前提是,连在一起的两端是同样一种颜色,然后这个额就很好理解,是一边画问题,求是否有欧拉路出现就好。

  无向图有欧拉路的条件:

  1.有0个或者2个点的度数为奇数。

  2.图是一个连通图。

  

  然后判断图连通,就是运用并查集的方法,每次合并一条边的两个顶点,最终一个连通图会合并成一个顶点,一个非连通图会合并成多个顶点,然后还要用路径压缩的方法,压缩一下路径。


  然后查找每一个单词的索引,由于数据量比较大,map可能比较慢,运用Trie树进行索引查找。

  

  题目有一个坑点是,可能里面有空数据,还要输出Possible。

  

#include "stdio.h"
#include "string.h"
#include "math.h"
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
using namespace std;

#define MAXM 1
#define MAXN 1
#define max(a,b) a > b ? a : b
#define min(a,b) a < b ? a : b
#define Mem(a,b) memset(a,b,sizeof(a))
int Mod = 1000000007;
double pi = acos(-1.0);
double eps = 1e-6;

typedef struct{
    int f,t,w,next;
}Edge;
Edge edge[MAXM];
int head[MAXN];
int kNum;

void addEdge(int f, int t, int w)
{
    edge[kNum].f = f;
    edge[kNum].t = t;
    edge[kNum].w = w;
    edge[kNum].next = head[f];
    head[f] = kNum ++;
}

char s1[15], s2[15];
int father[500005];
int indree[500005];


struct Node{
    bool flag;
    int id;
    struct Node *next[27];
    Node(){
        flag = false;
        id = -1;
        Mem(next, NULL);
    }
};

int find(int x){
    int s = x;
    while( father[x] != x ) x = father[x];
    for(int p = s; p != x; p = s){
        s = father[p];
        father[p] = x;
    }
    return x;
}

void Union(int x, int y){
    if( x < y ){
        father[y] = x;
    }
    else
        father[x] = y;
}

void solve(){
    kNum = 0;
    Mem(indree,0);

    struct Node* root = new struct Node;
    int id1, id2;
    while( scanf("%s %s", s1, s2) != EOF ){
//		getchar();
        struct Node *p = root;
        for(int i = 0; s1[i] != 0; i ++){
            if( p->next[s1[i] - 'a']  == NULL ){
                p->next[s1[i] - 'a'] = new struct Node; 
            }
            p = p->next[s1[i] -'a'];
        }
        if( !p->flag ){
            p ->flag = true;
            p ->id = kNum ++;
            father[p->id] = p->id;
        }
        id1 = p->id;

        p = root;
        for(int i = 0; s2[i] != 0; i ++){
            if( p->next[s2[i] - 'a']  == NULL ){
                p->next[s2[i] - 'a'] = new struct Node; 
            }
            p = p->next[s2[i] -'a'];
        }
        if( !p->flag ){
            p ->flag = true;
            p ->id = kNum ++;
            father[p->id] = p ->id;
        }
        id2 = p ->id;

        indree[id1] ++, indree[id2] ++;

        id1 = find(id1);
        id2 = find(id2);

        if( id1 != id2 ){
            Union(id1, id2);
        }

    }

    int num = 0;
    int s = find(0);
    for(int i = 0; i < kNum; i ++){
        if( indree[i] % 2 )
            num ++;
        if( num > 2 ){
            printf("Impossible\n");
            break;
        }
        if( find(i) != s ){
            printf("Impossible\n");
            break;
        }
        if( i == kNum - 1 ){
            if( num == 1 ){
                printf("Impossible\n");
            }
            else{
                printf("Possible\n");
            }
        }
    }
    if( kNum == 0 ){
        printf("Possible\n");
    }

}


int main()
{
//	freopen("d:\\test.txt", "r", stdin);

    solve();

    return 0;
}

    原文作者:Trie树
    原文地址: https://blog.csdn.net/kevin_liu11/article/details/46372385
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞