poj 2513 Colored Sticks (字典树+并查集+无向图的欧拉回路。)

来源:互联网 发布:单片机控制8个led灯 编辑:程序博客网 时间:2024/06/07 11:19

题目链接:http://poj.org/problem?id=2513


题目大意就是:给你一些棍子,每根棍子两端涂着颜色,颜色相同的两端可以连在一起,问所有棍子可不可以连在一起。

类似于hdu的1116(链接:http://acm.hdu.edu.cn/showproblem.php?pid=1116),差别是1116看的是字母,这看的是单词,这要麻烦些,而且1116是有向图,这是无向图。



字典树+并查集+无向图的欧拉回路。


1.一开始RE惨了,注意做多一共有50W个单词。

2.注意空输入时,输出Possible。

3.无向图。

4.题外话:在windows下,输入完毕后先按enter键,再按ctrl+z,最后再按enter,可以结束输入。


copy 一下:

欧拉回路:

1 定义

  欧拉通路 (欧拉迹) ——通过图中每条边一次且仅一次,并且过每一顶点的通路。

  欧拉回路 (欧拉闭迹) ——通过图中每条边一次且仅一次,并且过每一顶点的回路。

  欧拉图 ——存在欧拉回路的图。

无向图是否具有欧拉通路或回路的判定

  G有欧拉通路的充分必要条件为:G 连通,G中只有两个奇度顶点(它们分别是欧拉通路的两个端点)。

  G有欧拉回路(G为欧拉图):G连通,G中均为偶度顶点。

有向图是否具有欧拉通路或回路的判定

  D有欧拉通路:D连通,除两个顶点外,其余顶点的入度均等于出度,这两个特殊的顶点中,一个顶点的入度比出度大1,另一个顶点的入度比出度小1。

  D有欧拉回路(D为欧拉图):D连通,D中所有顶点的入度等于出度。


#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define M 510000int up,no,p[M],vis[M],deg[M];char s1[25],s2[25];struct node{    int next[26];    bool flag;    int num;    void init()    {        memset(next,0,sizeof(next));        num=-1;        flag=false;    }}root[M*10];int find(int t){    if(p[t]!=t)         return find(p[t]);    return t;}int build(char *s){    int i,p=0,id;    for(i=0;i<strlen(s);i++)    {        id=s[i]-'a';        if(root[p].next[id]==0)        {            root[p].next[id]=up;            root[up].init();            up++;        }        p=root[p].next[id];    }    if(!root[p].flag)//如果这个单词没有出现过,就给他一个新的编号    {        root[p].flag=true;        root[p].num=no;        no++;    }    return root[p].num;//返回单词编号}int main(){    int i,num=0,x=0,y=0,z=0;    for(i=0;i<M;i++)//父亲初始化     p[i]=i;    memset(vis,0,sizeof(vis));    memset(deg,0,sizeof(deg));//顶点度数    up=1;    no=0;    root[0].init();    while(scanf("%s%s",s1,s2)!=EOF)    {        int a=build(s1);        int b=build(s2);        vis[a]=vis[b]=1;        p[a]=p[b]=find(a);        deg[a]++;        deg[b]++;    }        if(no==0)        printf("Possible\n");//空输入        else       {           for(i=0;i<no;i++)           {              if(vis[i]&&p[i]==i)//父亲是自己的个数              {                num++;              }              if(vis[i]&&(deg[i]%2==1))//奇度数顶点                x++;           }           if(num!=1)//如果联通,应该父亲一样           printf("Impossible\n");           else          {             if(x==0||x==2)//无向图存在欧拉回路的条件。             printf("Possible\n");             else             printf("Impossible\n");          }       }    return 0;}



原创粉丝点击