彩色棒

来源:互联网 发布:手机上java编程的软件 编辑:程序博客网 时间:2024/04/27 20:50

彩色棒

时间限制:1000 ms  |  内存限制:128000 KB
难度:5
描述
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?
输入
the frist line have a number k(0<k<=10),that is the number of case. each case contais a number m,then have m line, 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 13 characters. There is no more than 250000 sticks.
输出
If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.
样例输入
15blue redred violetcyan blueblue magentamagenta cyan
样例输出
Possible

思路:

欧拉通路, 判断是否成线, 加并查集, 字典树优化。

#include <stdio.h>#include <string.h>#include <stdlib.h>typedef struct Node{int order;Node *next[26];}node;int cnt, father[250001], degree[250001];node *newnode()                            //新建节点{node *p = (node *)malloc(sizeof(node));for(int i = 0; i < 26; i++)                 //初始化节点{p->next[i] = NULL;}p->order = 0;return p;}int insert(node *root, char str[])              //将颜色插入字典树, 并返回颜色的编号{int len, flag = 0, i, pos;node *p = root;len = strlen(str);for(i = 0; i < len; i++){pos = str[i] - 'a';if(p->next[pos] == NULL){flag = 1;p->next[pos] = newnode();}p = p->next[pos];}if(flag)                      //若有新建节点, 则一定是新颜色, 记录编号, 并更新度数数组{p->order = cnt;degree[cnt++]++;}else{if(p->order == 0)        //若没有新建节点, 且p->order编号, 也是新颜色{p->order = cnt;degree[cnt++]++;}else{degree[p->order]++;}}return p->order;                 //返回节点编号}int findfather(int x)       //寻找根节点{if(father[x] == -1){return x;}else{return findfather(father[x]);}}int merge(int a, int b)      //将两个点合并到一个集合(并查集){a = findfather(a);b = findfather(b);if(a != b){father[a]=b;}return 0;}int main(){char str1[14], str2[14];int count, t1, t2, i, n, t;node *root;scanf("%d", &t);while(t--){root = newnode();memset(father, -1, sizeof(father));memset(degree, 0, sizeof(degree));scanf("%d", &n);if(n == 0)                    //若为空图直接返回Possible{printf("Possible\n");continue;}cnt = 1;                       //多组数据,别忘初始化for(i = 0; i < n; i++){scanf("%s%s", str1, str2);t1 = insert(root, str1);     //将颜色节点重新编号并归入并查集t2 = insert(root, str2);merge(t1, t2);}count = 0;                      //重新计数for(i = 1; i < cnt; i++){if(father[i] == -1){count++;}}if(count > 1)               //若有多个根节点则有多副图 ,无法连成一条线(成环时count有可能为0){printf("Impossible\n");continue;}count = 0;for(i = 1; i < cnt; i++)     //判断欧拉通路{if(degree[i]%2 == 1){count++;}}if(count == 2 || count == 0)  //若偶度节点只有2个(线)或没有(环),成立{printf("Possible\n");continue;}else                           //否则不成立{printf("Impossible\n");continue;}}return 0;}


0 0
原创粉丝点击