poj 1386 Play on Words(有向图欧拉回路)

/*
  题意:单词拼接,前一个单词的末尾字母和后一个单词的开头字母相同
  思路:将一个单词的开头和末尾单词分别做两个点并建一条有向边!然后判断是否存在欧拉回路或者欧拉路 

  再次强调有向图欧拉路或欧拉回路的判定方法:
(1)有向图G为欧拉图(存在欧拉回路),当且仅当G的基图连通,且所有顶点的入度等于出度。
(2)有向图G为半欧拉图(存在欧拉道路),当且仅当G的基图连通,且存在顶点u的入度比出度大1、v的入度比出度小1,
   其它所有顶点的入度等于出度(顶点u,v的个数必须都是1)。

   求该图的连通性的时候,只要求该有向图是弱连通的就可以了!所以转换为无向图的连通问题!
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

int g[30][30];
char ch[1005];
int vis[30], used[30];
int inD[30], outD[30];

void dfs(int u){
   vis[u]=1;
   for(int i=0; i<26; ++i)
      if(g[u][i] && !vis[i])
         dfs(i);
} 

bool checkDeg(){
    int inOut=0, outIn=0;
    for(int i=0; i<26; ++i)
       if(used[i] && inD[i]-outD[i]!=0){
          if(inD[i]-outD[i]>1 || inD[i]-outD[i]<-1) return false;
          else inD[i]-outD[i]>0 ? ++inOut : ++outIn;
       }
    return (inOut==1 && outIn==1) || (inOut==0 && outIn==0);
}

int main(){
    int n, t;
    scanf("%d", &t);
    while(t--){
        scanf("%d", &n);
        memset(vis, 0, sizeof(vis));
        memset(used, 0, sizeof(used));
        memset(g, 0, sizeof(g));
        memset(inD, 0, sizeof(inD));
        memset(outD, 0, sizeof(outD));
        while(n--){
           scanf("%s", ch);
           int u=ch[0]-'a', v=ch[strlen(ch)-1]-'a';
           g[u][v]=g[v][u]=1;//无向图的连通性 即是有向图的弱连通
           used[u]=used[v]=1;
           ++inD[v];
           ++outD[u];
        }
        bool flag=true;
        for(int i=0; i<26; ++i)
           if(used[i]){
              dfs(i);
              break;
           }
        for(int i=0; i<26; ++i)
           if(used[i] && !vis[i]){
              flag=false;
              break;
           }
        if(flag && !checkDeg())
           flag=false;
        if(flag)
           printf("Ordering is possible.\n");
        else printf("The door cannot be opened.\n");
    }
    return 0;
}
时间: 2024-12-01 13:38:55

poj 1386 Play on Words(有向图欧拉回路)的相关文章

POJ 1780 Code:十进制格雷码&amp;amp;欧拉回路

Description KEY Inc., the leading company in security hardware, has developed a new kind of safe. To unlock it, you don't need a key but you are required to enter the correct n-digit code on a keypad (as if this were something new!). There are severa

poj 2594Treasure Exploration(有向图路径可相交的最小路径覆盖)

#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #define N 505 using namespace std; int g[N][N]; int n, m; int vis[N], linker[N]; bool dfs(int u){ for(int i=1; i<=n; ++i) if(g[u][i] && !vis[i]){

POJ题目分类

初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      (4)递推.      (5)构造法.(poj3295)      (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法:      (1)图的深度优先遍历和广度优先遍历.      (2)最短路径算法(dijkstra,bellman-ford

poj 3164 Command Network:最小树形图模板题

链接: http://poj.org/problem?id=3164 题目: Command Network Time Limit: 1000MS     Memory Limit: 131072K Total Submissions: 8922     Accepted: 2609 Description After a long lasting war on words, a war on arms finally breaks out between littleken's and Knu

UVa 10054:The Necklace, 欧拉回路+打印路径

题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=105&page=show_problem&problem=995 题目类型: 欧拉回路 题目: My little sister had a beautiful necklace made of colorful beads. Two successive beads in the necklace sha

poj 1125 Floyd算法

一.题目大意 可以说理解题目比解题难~~明显的多源最短路径,我用的Floyd,Floyd也可以算是dp的一种. 题目可能有多组测试数据,每个测试数据的第一行为经纪人数量N(当N=0时,输入数据结束),然后接下来N行描述第i(1<=i<=N)个经纪人与其他经纪人的关系.每行开头数字M为该行对应的经纪人有多少个经纪人朋友(该节点的出度,可以为0),然后紧接着M对整数,每对整数表示成a,b,则表明该经纪人向第a个经纪人传递信息需要b单位时间(即第i号结点到第a号结点的孤长为b),整张图为有向图,即弧

poj分类

初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      (4)递推.      (5)构造法.(poj3295)      (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法:      (1)图的深度优先遍历和广度优先遍历.      (2)最短路径算法(dijkstra,bellman-ford

NYOJ 99单词拼接(有向图的欧拉(回)路)

/* NYOJ 99单词拼接: 思路:欧拉回路或者欧拉路的搜索! 注意:是有向图的!不要当成无向图,否则在在搜索之前的判断中因为判断有无导致不必要的搜索,以致TLE! 有向图的欧拉路:abs(In[i] - Out[i])==1(入度[i] - 出度[i])的节点个数为两个 有向图的欧拉回路:所有的节点都有In[i]==Out[i] */ #include<iostream> #include<cstring> #include<cstdio> #include<

【POJ 1330 Nearest Common Ancestors】LCA问题 Tarjan算法

题目链接:http://poj.org/problem?id=1330 题意:给定一个n个节点的有根树,以及树中的两个节点u,v,求u,v的最近公共祖先. 数据范围:n [2, 10000] 思路:从树根出发进行后序深度优先遍历,设置vis数组实时记录是否已被访问. 每遍历完一棵子树r,把它并入以r的父节点p为代表元的集合.这时判断p是不是所要求的u, v节点之一,如果r==u,且v已访问过,则lca(u, v)必为v所属集合的代表元.p==v的情况类似. 我的第一道LCA问题的Tarjan算法