zoukankan      html  css  js  c++  java
  • hdu 1116 Play on Words(欧拉通路)

    题意:给出给出n个单词,要求判断这些单词能否接龙,规则像成语接龙一样,就是当前单词的尾字母为下一个单词的首字母。

    思路:看着像是欧拉通路相关的题目,但是重点就在于怎么抽象出来。

    刚开始想了半天没想明白,老想着一个单词作为一个顶点去了,就是没转过来。

    看了篇解题报告(http://blog.csdn.net/niushuai666/article/details/6917777) 后想过来了,

    应该把单词的首尾字母看成顶点,而这个单词相当于连接顶点的有向边。然后这样想的话,这个图最多就有26个顶点(因为只有26个小写字母,题目要求单词为小写字母),接下来就是怎么判断这个途中是否存在欧拉通路了(即判断是否为半欧拉图或欧拉图)。

    关于欧拉图的相关知识,详见:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    #define MAXN 26//最多26个点
    
    int fa[MAXN];
    bool exist[MAXN];//标记点是否存在
    int in[MAXN],out[MAXN];//入度,出度
    int diff[MAXN];//入度不等于出度的点
    
    int set_find(int d){
        if(fa[d]<0)return d;
        return fa[d]=set_find(fa[d]);
    }
    
    void set_join(int x,int y){
        x=set_find(x);
        y=set_find(y);
        if(x!=y)fa[x]=y;
    }
    
    int main(){
        int t,n,i;
        char word[1024];//单词
        int a,b;//首字母,尾字母
        int root;//根节点数目
        int m;//入度不等于出度的点的个数
        scanf("%d",&t);
        while(t--){
            memset(fa,-1,sizeof(fa));
            memset(exist,0,sizeof(exist));
            memset(in,0,sizeof(in));
            memset(out,0,sizeof(out));
            root=0;
            m=0;
            scanf("%d",&n);
            while(n--){
                scanf("%s",word);
                a=word[0]-'a';
                b=word[strlen(word)-1]-'a';
                exist[a]=exist[b]=true;
                ++out[a];
                ++in[b];
                set_join(b,a);//b连到a上
            }
            for(i=0;i<MAXN;++i)
                if(exist[i]&&fa[i]<0)++root;
            if(root>1)printf("The door cannot be opened.
    ");//图不连通
            else{
                for(i=0;i<MAXN;++i)
                    if(in[i]!=out[i])diff[m++]=i;
                if(m==0)printf("Ordering is possible.
    ");//所有点入度等于出度,为欧拉图
                else if(m==2&&(
                            (in[diff[0]]-out[diff[0]]==1&&out[diff[1]]-in[diff[1]]==1)||
                            (out[diff[0]]-in[diff[0]]==1&&in[diff[1]]-out[diff[1]]==1) )
                        )printf("Ordering is possible.
    ");//满足半欧拉图条件,为半欧拉图
                else printf("The door cannot be opened.
    ");//不是欧拉图,也不是半欧拉图
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Windows Phone 7 日期选择控件DatePicker和时间选择控件TimePicker
    Windows Phone 7 开发小技巧
    Windows Phone 7 MVVM模式的学习笔记
    Windows Phone 7 网络编程之留言板应用
    C# 中的INotifyPropertyChanged和ObservableCollection<T>
    《深入浅出:Windows Phone 7应用开发》
    Windows Phone 7 MVVM模式通讯方式之实现Command
    Windows Phone 7 chart图表编程
    Windows Phone 7 网络编程之调用web service
    Perst嵌入式数据库介绍
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4731095.html
Copyright © 2011-2022 走看看