zoukankan      html  css  js  c++  java
  • POJ2513-Colored Sticks

    题目链接:点击打开链接

    Colored Sticks

    Time Limit: 5000MS   Memory Limit: 128000K
    Total Submissions: 39392   Accepted: 10271

    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.

    题目大意:给出n根木棒,木棒两段颜色,只有颜色相同才可以连接,问是否能连成一根木棒。

    思路:颜色转化成数字。两个方法:①map(超时)②字典树。 连成一根木棒,并查集+欧拉回路

    AC代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstdlib> 
    #include<cstring>
    using namespace std;
    const int MAXN = 500010;
    int father[MAXN];
    const int MAX = 26;
    int degree[MAXN];//度数 
    int color;
    //并查集************************ 
    int find(int x) { 
    	if(father[x] == -1)
    		return x;
    	return father[x] = find(father[x]);
    }
    
    void Union(int x, int y) {
    	int fx = find(x);
    	int fy = find(y);
    	if(fx != fy)
    		father[fx] = fy;
    }
    //字典树**************************** 
    typedef struct Trie_Node{ 
    	bool isword;//是否是单词结束 
    	int id;//编号 
    	struct Trie_Node *next[MAX];
    	Trie_Node() {//初始化 
    		isword = false;
    		int id = 0;
    		for(int i = 0; i < MAX; i++)
    			next[i] = NULL;
    	}
    }trie;
    
    int insert(trie *root, char *s) {
    	trie *p = root;
    	int i = 0;
    	while(s[i]) {//跑s串 
    		if(p->next[s[i]-'a'] == NULL) {//如果该位置 找不到 s[i], 就开一个,指向它 
    			trie *temp = new trie();
    			p->next[s[i]-'a'] = temp;
    		} 
    		p = p->next[s[i]-'a'];//继续跑 
    		i++;
    	}
    	if(p->isword)//如果之前有过了,直接返回编号 
    		return p->id;
    	else {//之前没有,就先标记,然后赋值,返回值。 
    		p->isword = true;
    		p->id = color++;
    		return p->id;
    	}
    }
    
    void del(trie *root) {//删除 
    	for(int i = 0; i < 26; i++) {
    		if(root->next[i] != NULL)//这个节点还有26个 
    			del(root->next[i]);
    	}
    	free(root);
    } 
    
    int main() {
    	char s1[20], s2[20];
    	trie *root = new trie();
    	color = 0;
    	memset(father, -1, sizeof(father));//初始-1  并查集都可以这样写,这道题的颜色编号每处理,这样写更好 
    	memset(degree, 0, sizeof(degree));
    	while(~scanf("%s%s", s1, s2)) {
    		int t1 = insert(root, s1);//插入字典树,返回编号 
    		int t2 = insert(root, s2);
    		degree[t1]++;//入读++ 
    		degree[t2]++;
    		Union(t1, t2);
    	}
    	bool flag = true;
    	int tt = find(0);//找到根,每个的祖先都应该是它 
    	int cnt = 0;
    	for(int i = 0; i < color; i++) {
    		if(find(i) != tt) flag = false;
    		if(!flag) break;
    		if(degree[i]%2 == 1) cnt++;// 度数为奇数只能是0 或者 2 
    		if(cnt > 2) flag = false;
    	}
    	if(cnt == 1) flag =false;
    	if(flag) printf("Possible
    ");
    	else printf("Impossible
    ");
    	del(root);
    }
    
    

     推荐博客:神犇kuangbin        浅谈字典树

  • 相关阅读:
    mysql练习(增删改查)char、int使用
    mysql基于二进制安装
    Mysql架构、复制类型、复制功能介绍
    day44 前端之前端基础
    MySQL之事务、视图和索引
    MySQL的练习与pymysql模块
    MySQL之表的查询
    MySQL之表的关系和约束
    MySQL之基本数据类型
    MySQL数据库
  • 原文地址:https://www.cnblogs.com/ACMerszl/p/9572963.html
Copyright © 2011-2022 走看看