• POJ 2513


    题目链接:

    http://poj.org/problem?id=2513

    http://bailian.openjudge.cn/practice/2513?lang=en_US

    Time Limit: 5000MS Memory Limit: 128000K

    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

    Hint

    Huge input,scanf is recommended.

    题意:

    给出若干木棒,每个木棒两个端点有两个颜色,两个木棒的端点颜色相同,则可以接在一起。问是否把所有木棒接成一根。

    题解:

    (参考http://blog.csdn.net/lyy289065406/article/details/6647445

    将每个颜色都看成一个节点,木棒就能看成一条连接两个端点的无向边。问题就变成在给定一个无向图问是否存在欧拉路

    欧拉路存在的充要条件是:① 图是连通的; ② 所有节点的度为偶数,或者有仅有两个度数为奇数的节点。

    这道题,求顶点的度数很好求,但是怎么判断图是否连通呢?通常来说,DFS/BFS或者并查集都能做。

    不过,本题字典树的用处就是代替map,将输入字符串快速hash成一个值。

    AC代码(BFS判图的连通性):

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=250000+10;
    
    int degree[2*maxn];
    vector<int> G[2*maxn];
    
    namespace Trie
    {
        const int SIZE=maxn*10;
        int sz;
        int idtot;
        struct TrieNode{
            int ed;
            int nxt[26];
        }trie[SIZE];
        void init()
        {
            idtot=0;
            sz=1;
        }
        int insert(const string& s)
        {
            int p=1;
            for(int i=0;i<s.size();i++)
            {
                int ch=s[i]-'a';
                if(!trie[p].nxt[ch]) trie[p].nxt[ch]=++sz;
                p=trie[p].nxt[ch];
            }
            if(!trie[p].ed) trie[p].ed=++idtot;
            return trie[p].ed;
        }
    };
    
    bool vis[2*maxn];
    int bfs(int s)
    {
        int res=0;
        memset(vis,0,sizeof(vis));
        queue<int> Q;
        Q.push(s), vis[s]=1, res++;
        while(!Q.empty())
        {
            int u=Q.front(); Q.pop();
            for(int i=0;i<G[u].size();i++)
            {
                int v=G[u][i];
                if(!vis[v]) Q.push(v), vis[v]=1, res++;
            }
        }
        return res;
    }
    
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
    
        string s1,s2;
        Trie::init();
        while(cin>>s1>>s2)
        {
            int u=Trie::insert(s1), v=Trie::insert(s2);
            G[u].push_back(v);
            G[v].push_back(u);
            degree[u]++;
            degree[v]++;
        }
    
        int cnt=0;
        for(int i=1;i<=Trie::idtot;i++) {
            if(degree[i]%2) cnt++;
        }
        if(cnt==1 || cnt>2) cout<<"Impossible
    ";
        else
        {
            if(bfs(1)<Trie::idtot) cout<<"Impossible
    ";
            else cout<<"Possible
    ";
        }
    }

    AC代码(并查集判图的连通性):

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=250000+5;
    
    namespace Trie
    {
        const int SIZE=maxn*10;
        int sz;
        int idcnt;
        struct TrieNode{
            int ed;
            int nxt[26];
        }trie[SIZE];
        void init()
        {
            idcnt=0;
            sz=1;
        }
        int insert(char *s)
        {
            int len=strlen(s), p=1;
            for(int i=0;i<len;i++)
            {
                int ch=s[i]-'a';
                if(!trie[p].nxt[ch]) trie[p].nxt[ch]=++sz;
                p=trie[p].nxt[ch];
            }
            return (trie[p].ed)?(trie[p].ed):(trie[p].ed=++idcnt);
        }
    };
    
    int par[2*maxn],ran[2*maxn];
    int find(int x){return (par[x]==x)?x:(par[x]=find(par[x]));}
    void unite(int x,int y)
    {
        x=find(x), y=find(y);
        if(x==y) return;
        if(ran[x]<ran[y]) par[x]=y;
        else par[y]=x, ran[x]+=(ran[x]==ran[y]);
    }
    
    int degree[2*maxn];
    int main()
    {
        Trie::init();
        memset(degree,0,sizeof(degree));
        for(int i=1;i<2*maxn;i++) par[i]=i,ran[i]=0;
    
        char s[2][13];
        while(scanf("%s %s",s[0],s[1])!=EOF)
        {
            int u=Trie::insert(s[0]);
            int v=Trie::insert(s[1]);
            if(find(u)!=find(v)) unite(u,v);
            degree[u]++;
            degree[v]++;
        }
    
        int cnt=0;
        int z=find(1);
        for(int i=1;i<=Trie::idcnt;i++)
        {
            if(find(i)!=z) {
                printf("Impossible
    ");
                return 0;
            }
    
            if(degree[i]%2) cnt++;
            if(cnt>2) {
                printf("Impossible
    ");
                return 0;
            }
        }
        if(cnt==1) {
            printf("Impossible
    ");
            return 0;
        } else {
            printf("Possible
    ");
            return 0;
        }
    }
  • 相关阅读:
    ArcEngine连接表join
    坐标系统与投影变换及在ARCGIS中的应用
    ArcEngine 最短路径分析(源码)【转载】
    TOC图例符号转换到ListView
    Dijkstra 最短路径算法的一种高效率实现
    添加、删除连接(Join)和关联(Relate)VBA实例
    C# 实现在线软件自动升级程序
    MapX八个技巧
    希腊字母的读法
    经纬度点与投影坐标系下坐标点的互相转换
  • 原文地址:https://www.cnblogs.com/dilthey/p/6843445.html
Copyright © 2020-2023  润新知