问一个无向图是否存在欧拉路径。

条件:在无向图中,奇度点为2,其余都为偶度点。

端点有字典树处理即可。

 

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;

const int maxn = 500010;

int n, m;

int fa[maxn];
int ind[maxn];
int outd[maxn];
bool vis[maxn];

int find(int x)
{
    return x == fa[x]? x : fa[x] = find(fa[x]);
}

void Union(int x, int y)
{
    x = find(x), y = find(y);
    if(x == y) return ;
    fa[x] = y;
}

void init()
{
    memset(ind, 0, sizeof(ind));
    memset(outd, 0, sizeof(outd));
    memset(vis, 0, sizeof(vis));
    for(int i = 1; i < maxn; i++) fa[i] = i;
}

void readint(int &x)
{
    char c;
    while(!isdigit(c)) c = getchar();
    
    x = 0;
    while(isdigit(c))
    {
        x = x*10 + c-'0';
        c = getchar();
    }
}

void writeint(int x)
{
    if(x > 9) writeint(x/10);
    putchar(x%10+'0');
}

int check()
{
    int count = 0;
    for(int i = 1; i <= n; i++) if(vis[i] && fa[i] == i) count++;
    if(count > 1) return 0;
    
    int c1 = 0;
    for(int i = 1; i <= n; i++) if(vis[i])
    {
        if((ind[i]+outd[i]) & 1) c1++;
    }
    if(c1 == 2 || c1 == 0) return 1;
    return 0;
}

const int maxnode = 500010;
const int sigma_size = 26;

struct Trie
{
    int ch[maxnode][sigma_size];
    int val[maxnode];
    int sz;
    int v;
    void init() { sz = 1; v = 0; memset(ch[0], 0, sizeof(ch[0])); }
    int idx(char c) { return c-'a'; }
    
    int insert(char *s)
    {
        int u = 0, n = strlen(s);
        for(int i = 0; i < n; i++)
        {
            int c = idx(s[i]);
            if(!ch[u][c])
            {
                memset(ch[sz], 0, sizeof(ch[sz]));
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        if(val[u] != 0) return val[u];
        else
        {
            val[u] = ++v;
            return v;
        }
    }
}trie;

int main()
{
    int T = 0;
    init();
    trie.init();
    
    char s1[20], s2[20];
    while(~scanf("%s%s", &s1, &s2))
    {
        int x = trie.insert(s1), y = trie.insert(s2);
        vis[x] = vis[y] = 1;
        outd[x]++, ind[y]++;
        Union(x, y);
        T++;
    }
    n = trie.v;
    if(T == 0) { printf("Possible\n"); return 0; }
    if(check()) printf("Possible\n");
    else printf("Impossible\n");
}
View Code

 

 

 

posted on 2013-08-04 22:55  Buck Meister  阅读(282)  评论(0编辑  收藏  举报