POJ-2513 Colored Sticks

原创 2018年04月17日 17:07:21

Colored Sticks
题目链接
Time Limit: 5000MS Memory Limit: 128000K
Total Submissions: 38621 Accepted: 10108
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.
Source

The UofA Local 2000.10.14

题目大意
给出不超过250000根木棒,木棒两端有颜色,请按照一定顺序把木棒两两连接,使得所有木棒连成一条直线。
我们只可以把颜色相同的两个端点连起来。
单词(颜色)长度不超过10。

题解
已知有两种解法

第一种:
很明显就是判断欧拉通路或欧拉回路。判断连通性,所以肯定要用到并查集。然后再统计一趟入度出度,判断是否是欧拉图。
为了方便处理,我们肯定要排序。而木棒又有两头,我们就干脆把两头拆开,并带上这根木棍的信息,再排序,这样只需把相同的一段内的木棍信息合并就好了。

第二种:
和第一种的核心差不多,把排序改成用Trip树。

代码
排序+并查集

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=250005;
int n,m,fa[maxn],h[maxn];
struct js{
    char s[11];
    int id;//木棒信息
}a[maxn<<1];//一分为二后大小要开两倍
int get(int x){return (fa[x]==x)?x:fa[x]=get(fa[x]);}
bool cmp(js a,js b)
{
    int i=0;
    while (a.s[i]||b.s[i])
    {
        if (a.s[i]!=b.s[i])
          return a.s[i]<b.s[i];
        i++;
    }
    return 0;
}
void read(char *s)
{
    int x=0;char ch=getchar();
    while (ch!=EOF&&(ch<'a'||ch>'z')) ch=getchar();
    if (ch==EOF) {s[0]='@';return;}
    while (ch>='a'&&ch<='z') s[x]=ch,x++,ch=getchar();
    s[x]=0;
}
bool pd(js a,js b)
{
    int i=0;
    while (a.s[i]||b.s[i])
      if (a.s[i]!=b.s[i]) return 0;
      else i++;
    return 1;
}
int main()
{
    m=0;
    while (1)
    {
        m++;
        read(a[m].s);
        if(a[m].s[0]=='@') break;
        a[m].id=m+1>>1;
        m++;
        read(a[m].s);
        a[m].id=m+1>>1;
    }
    m--;n=m>>1;
    for (int i=1;i<=n;i++) fa[i]=i;
    sort(a+1,a+m+1,cmp);
    int now=1;h[1]=1;
    for (int i=1;i<m;i++)
    {
        if (pd(a[i],a[i+1]))
        {
            int fx=get(a[i].id),fy=get(a[i+1].id);
            if (fx!=fy) fa[fx]=fy;
            h[now]++;
        }else h[++now]=1;
    }
    int lst=get(1),s=0;
    for (int i=2;i<=n;i++)
      if (get(i)!=lst) {printf("Impossible");return 0;}
    for (int i=1;i<=now;i++)
      if (h[i]&1) s++;
    if (s<3) printf("Possible");
        else printf("Impossible");
    return 0;
}

Trip树+并查集

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=250005;
int n,m,sum,fa[maxn];
char s[11];
struct trip_node{
    int val,s;
    trip_node *nxt[26];
    trip_node(){val=0;s=0;for(int i=0;i<26;i++)nxt[i]=NULL;}//初始化
}*rot=new trip_node;
int get(int x){return (fa[x]==x)?x:fa[x]=get(fa[x]);}
void Insert(char *s,int len,int tot)
{
    trip_node *x=rot;
    for (int i=0;i<=len;i++)
    {
        int id=s[i]-'a';
        if (x->nxt[id]==NULL) x->nxt[id]=new trip_node;//创建新节点
        x=x->nxt[id];
        if (i==len)
        {
            if (!x->val) x->val=tot;
            int fx=get(x->val),fy=get(tot);
            if (fx!=fy) fa[fx]=fy;
            //并查集合并
            if ((++(x->s))&1) sum++;else sum--;
        }
    }
}
void read(char *s){s[0]=0;scanf("%s",s);}
int main()
{
    n=0;
    for (int i=1;i<=250000;i++) fa[i]=i;
    while (1)
    {
        read(s);
        if(s[0]==0) break;
        n++;
        Insert(s,strlen(s)-1,n);
        read(s);
        Insert(s,strlen(s)-1,n);
    }
    if (!n) {printf("Possible");return 0;}
    if (sum>2) {printf("Impossible");return 0;}
    int lst=get(1);
    for (int i=2;i<=n;i++)
      if (get(i)!=lst) {printf("Impossible");return 0;}
    printf("Possible");
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xu0_zy/article/details/79975154

poj-2513 Colored Sticks

Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with som...
  • chAngE_AC
  • chAngE_AC
  • 2015-08-17 09:32:01
  • 170

POJ-2513 Colored Sticks【并查集+Trie+欧拉路】

题目链接:http://poj.org/problem?id=2513   题目大意: 有N根木棒,一根木棒有2头,我们把每头涂色(相同或不同),如果2根木棒有相同颜色的一端就可以连接,颜色全部...
  • niushuai666
  • niushuai666
  • 2012-04-13 13:09:04
  • 3922

POJ-2513 Colored Sticks(字典树+并查集+欧拉)

题目链接:Colored Sticks 一道3个知识点结合的题目,可以说单个知识点的题目,都会做,一旦知识点结合起来,题目就不简单了 思路:这个题开始看就知道是并查集,但是不好处理的不同种单词的统...
  • u013497151
  • u013497151
  • 2014-07-28 18:49:20
  • 876

Colored Sticks

Colored Sticks Time Limit:5000MS     Memory Limit:128000KB     64bit IO Format:%I64d & %I64u Sub...
  • u013022160
  • u013022160
  • 2014-07-28 21:33:41
  • 508

poj2513——Colored Sticks

tire树+并查集+欧拉路将木棍端点颜色看做顶点,木棍本身作为边,利用tire树求其"顶点",用并查集来判断是否连通,而欧拉路的判断,在连通的基础上,则是每个点的度数为偶数,或者为度奇数的点只有2个!...
  • k1246195917
  • k1246195917
  • 2010-11-09 10:58:00
  • 261

pku 2513 Colored Sticks

题目意思:给出若干两端染色的木棍,两根木棍相同颜色的一端可以连在一起,问所有木棍能否连成一条解题思路:网上普遍的解法:字典树+并查集+欧拉通路 每输入一种颜色都让它插入到树中,并给每种颜色编号--第一...
  • skywalker_sun
  • skywalker_sun
  • 2010-04-22 16:10:00
  • 310

poj 2513 colored sticks

算法,欧拉路判定: 1. 图连通 2. 奇度点个数是 0 或 2   实现,哈希表保存 + 并查集判连通 #include #include #include #include #i...
  • chengouxuan
  • chengouxuan
  • 2011-05-25 15:48:00
  • 200

周赛-Colored Sticks

Colored Sticks Time Limit: 5000MS Memory Limit: 128000K Total Submissions: 32423 Accep...
  • huayunhualuo
  • huayunhualuo
  • 2015-08-02 09:33:06
  • 147

poj Colored Sticks(2513)

Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 30201 ...
  • u010452161
  • u010452161
  • 2014-08-12 15:39:35
  • 431

【POJ 2513】Colored Sticks

【POJ 2513】Colored Sticks
  • ChallengerRumble
  • ChallengerRumble
  • 2015-08-02 21:29:34
  • 691
收藏助手
不良信息举报
您举报文章:POJ-2513 Colored Sticks
举报原因:
原因补充:

(最多只允许输入30个字)