自己的代码超时了。。。不应该啊,方法没错哦,明天检查一下吧,网上看到一份不错的代码,不是针对于该题目,而是打印中间过程的方法,很细致,非常有利于debug

#include <stdio.h>   
#include <string.h>   
  
//#define DEBUG   
  
#ifdef DEBUG   
#define debug(...) printf( __VA_ARGS__)    
#else   
#define debug(...)   
#endif   
  
#define M 530001   
#define N 500001   
  
struct trie_node {   
    int color_id;           /* 叶子节点存储颜色编号,从1开始 */  
    int child[26];          /* 分支节点,静态链表表示 */  
};   
struct trie_node trie_tree[M];  /* trie树的静态链表表示法,trie_tree[0]是树根 */  
int  current;                   /* Trie树当前使用了多少个节点 */  
  
int  parent[N];                 /* 并查集树形表示,parent[u] = r,若r > 0,u的  
                                   父亲为r, 若r < 0, 则u是根节点,其高度为-r */  
int  degree[N];   
int  n;                         /*顶点个数, 即有多少种颜色 */  
  
/* 把单词插入Trie树,如果单词已存在直接返回颜色编号,  
 * 不存在则插入,同时返回新生成的颜色编号   
 */  
int insert(char *color)   
{   
    char                *p;   
    struct trie_node    *node;   
    int                 new_node;   
  
    node = trie_tree;   
    //沿着树根一直往下插   
    for (p = color; *p != '\0'; p++) {   
        debug("开始插入 %c...\n", *p);   
        if (node->child[*p-'a'] == 0) {   
            debug("没有%c, 新建节点\n", *p);   
            node->child[*p-'a'] = current++;   
        }   
        else {   
            debug("存在%c\n", *p);   
        }   
        node = trie_tree + node->child[*p-'a'];   
    }   
    //到达记录统计单词次数的节点   
    if (node->color_id == 0) {   
        node->color_id = ++n;   
    }    
    debug("%s插入完成,其编号为%d\n", color, node->color_id);   
    return node->color_id;   
}   
  
/* 找i的根节点 */  
int find(int i)   
{   
    for(; parent[i] > 0; i = parent[i]) ;   
    return i;   
}   
  
void merge(int x,int y)   
{   
    int     px, py;   
  
    px = find(x);   
    py = find(y);   
    if (px == py) return;   
    debug("%d的树根为%d,树高=%d,%d的树根为%d, 树高=%d\n", x, px, -parent[px], y, py, -parent[py]);   
    if (parent[px] < parent[py]) {   /* x所在的树比y所在的树要高 */  
        parent[py] = px;   
        debug("合并后树根为%d, 高度=%d\n", px, -parent[px]);   
    }   
    else if (parent[px] > parent[py]) { /* x所在的树比y所在的树要矮 */  
        parent[px] = py;   
        debug("合并后树根为%d, 高度=%d\n", py, -parent[py]);   
    }   
    else {   
        parent[py] = px;   
        parent[px]--;   /* 树的高度加1 */  
        debug("合并后树根为%d, 高度=%d\n", px, -parent[px]);   
    }   
}   
  
int main()   
{   
    char    color1[11], color2[11];   
    int     u, v, subgraph, count;   
  
    current = 1;   
    n = 0;   
    memset(parent, -1, sizeof(parent));   
    memset(degree, 0, sizeof(degree));   
  
    while (scanf("%s %s", color1, color2) != EOF) {   
        u = insert(color1);   
        v = insert(color2);   
        degree[u]++;   
        degree[v]++;   
        merge(u, v);   
    }   
  
    //空数据打印Possible, 否则Wrong Answer   
    if (n == 0) {   
        printf("Possible\n");   
        return 0;   
    }   
  
    //计算奇数度顶点的个数   
    count = 0;   
    for (u = 1; u <= n; u++) {   
        if (degree[u]%2 != 0) {   
            if(++count > 2) break;   
        }   
    }   
    debug("奇数度的顶点个数为%d\n", count);   
  
    /* 计算并查集有几个分支,只有一个分支,说明图是连通的,   
     * 如果有两个或两个以上的分支,则图不是连通的  
     */  
    subgraph = 0;   
    if (count == 0 || count == 2) {   
        for (u = 1; u <= n; u++) {   
            /* parent[u] < 0说明u是树根,有多少树根,并查集就有多少个分支 */  
            if (parent[u] < 0) {    
                if (++subgraph > 1) {   
                    break;   
                }   
            }   
        }   
        if (subgraph == 1) {   
            printf("Possible\n");   
            return 0;   
        }   
    }   
    printf("Impossible\n");   
    return 0;   
}  
posted on 2011-10-25 00:09  geeker  阅读(283)  评论(0编辑  收藏  举报