hdu1116 欧拉回路

  1 //Accepted    248 KB    125 ms
  2 //欧拉回路
  3 //以26个字母为定点,一个单词为从首字母到末尾字母的一条边
  4 //下面就是有向图判断欧拉回路
  5 //连通+节点入度和==出度和 或者 存在一对节点一个入度比出度大1,一个小1
  6 #include <cstdio>
  7 #include <cstring>
  8 #include <iostream>
  9 #include <queue>
 10 using namespace std;
 11 const int imax_n = 30;
 12 int a[imax_n][imax_n];
 13 bool used[imax_n];
 14 bool vis[imax_n];
 15 int cnt_in[imax_n],cnt_out[imax_n];
 16 int n;
 17 char s[1005];
 18 queue<int >q;
 19 void bfs(int s)
 20 {
 21     while (!q.empty()) q.pop();
 22     //if (used[s]==0) return 0;
 23     q.push(s);
 24     vis[s]=1;
 25     while (!q.empty())
 26     {
 27         int x=q.front();
 28         q.pop();
 29         for (int i=1;i<imax_n;i++)
 30         {
 31             if (used[i]==1 && !vis[i] && a[x][i])
 32             {
 33                 vis[i]=1;
 34                 q.push(i);
 35             }
 36         }
 37     }
 38 }
 39 bool judge()
 40 {
 41     int flag;
 42     for (int i=1;i<=26;i++)
 43     {
 44         memset(vis,0,sizeof(vis));
 45         bfs(i);
 46         flag=1;
 47         for (int j=1;j<=26;j++)
 48         if (used[j]==1 && !vis[j]) flag=0;
 49         if (flag==1) return 1;
 50     }
 51     return 0;
 52 }
 53 bool slove()
 54 {
 55     int p,ne;
 56     p=ne=0;
 57     for (int i=1;i<=26;i++)
 58     {
 59         int t=cnt_in[i]-cnt_out[i];
 60         if (t==0) continue;
 61         if (t==1)
 62         {
 63             p++;
 64             if (p>=2) return 0;
 65             continue;
 66         }
 67         if (t==-1)
 68         {
 69             ne++;
 70             if (ne>=2) return 0;
 71             continue;
 72         }
 73         return 0;
 74     }
 75     if (!(p==1 && ne==1 || p==0 && ne==0)) return 0;
 76     return 1;
 77 }
 78 int main()
 79 {
 80     int T;
 81     scanf("%d",&T);
 82     while (T--)
 83     {
 84         scanf("%d",&n);
 85         int x,y;
 86         memset(a,0,sizeof(a));
 87         memset(used,0,sizeof(used));
 88         memset(cnt_in,0,sizeof(cnt_in));
 89         memset(cnt_out,0,sizeof(cnt_out));
 90         for (int i=0;i<n;i++)
 91         {
 92             scanf("%s",s);
 93             int l=strlen(s);
 94             x=s[0]-‘a‘+1;
 95             y=s[l-1]-‘a‘+1;
 96             used[s[0]-‘a‘+1]=true;
 97             used[s[l-1]-‘a‘+1]=true;
 98             a[x][y]=1;
 99             cnt_out[x]++;
100             cnt_in[y]++;
101         }
102         if (judge()==1 && slove()==1)
103         printf("Ordering is possible.\n");
104         else
105         printf("The door cannot be opened.\n");
106     }
107     return 0;
108 }

时间: 2024-10-13 21:54:07

hdu1116 欧拉回路的相关文章

HDU1116(欧拉回路+并查集)

先用并查集来判断图是否连通,然后再根据欧拉回路的出度和入度的性质来判断是否为欧拉回路. 关键是建边,我们可以把字符串看成是一条边,首字母为出发点,尾字母为目的点,建边. #include <stdio.h> #include <string.h> #include <string> #include <iostream> #include <algorithm> #include <vector> #include <math.

混合图的欧拉回路判定

对于有向图和无向图的欧拉回路判定,很容易做到.那对于混合图呢?? 混合图就是图中既存在无向边又存在有向边的图. 至于解法: 转载自这里 把该图的无向边随便定向,计算每个点的入度和出度.如果有某个点出入度之差为奇数,那么肯定不存在欧拉回路.因为欧拉回路要求每点入度 = 出度,也就是总度数为偶数,存在奇数度点必不能有欧拉回路. 好了,现在每个点入度和出度之差均为偶数.那么将这个偶数除以2,得x.也就是说,对于每一个点,只要将x条边改变方向(入>出就是变入,出>入就是变出),就能保证出 = 入.如果

POJ 1041 John&#39;s trip 无向图的【欧拉回路】路径输出

欧拉回路第一题TVT 本题的一个小技巧在于: [建立一个存放点与边关系的邻接矩阵] 1.先判断是否存在欧拉路径 无向图: 欧拉回路:连通 + 所有定点的度为偶数 欧拉路径:连通 + 除源点和终点外都为偶数 有向图: 欧拉回路:连通 + 所有点的入度 == 出度 欧拉路径:连通 + 源点 出度-入度=1 && 终点 入度 - 出度 = 1 && 其余点 入度 == 出度: 2.求欧拉路径 : step 1:选取起点(如果是点的度数全为偶数任意点为S如果有两个点的度数位奇数取一

寒假集训日志(二)——最小生成树,拓扑排序,欧拉回路,连通路

今天学的内容挺多的. (一)首先说最小生成树,两种算法: 1.Kruskal算法( 将边排序,然后再选,关键在于检查是否连通,使用并查集) 2.Prim算法(使用点集,有点类似与最短路的算法) 第一题是并查集算法的使用: A - The Suspects Time Limit:1000MS     Memory Limit:20000KB     64bit IO Format:%I64d & %I64u Submit Status Description 严重急性呼吸系统综合症( SARS),

HDU-1878 判断无向图欧拉回路,水

HDU 1878 题意:问一个无向图是否存在欧拉回路. 总结: 1.一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图.2.一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图.3.要判断一个混合图G(V,E)(既有有向边又有无向边)是欧拉图,方法如下:假设有一张图有向图G',在不论方向的情况下它与G同构.并且G'包含了G的所有有向边.那么如果存在一个图G'使得G'存在欧拉回路,那么G就存在欧拉回路. // HDU-1878 #include<bits/stdc++

HDU 5883 F - The Best Path 欧拉通路 &amp; 欧拉回路

给定一个图,要求选一个点作为起点,然后经过每条边一次,然后把访问过的点异或起来(访问一次就异或一次),然后求最大值. 首先为什么会有最大值这样的分类?就是因为你开始点选择不同,欧拉回路的结果不同,因为是回路,所以你的开始点就会被访问多一次,所以如果是欧拉回路的话,还需要O(n)扫一次,枚举每个点作为起点. 欧拉通路的话,结果是固定的,因为只能从奇数度小的那个点作为起点,奇数度大的那个点作为终点. 关于点的访问次数:anstime  = Degree[i] / 2; //如果是奇数的,还要加上一.

HDU5883 The Best Path(欧拉回路 | 通路下求XOR的最大值)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5883 思路: 先判断原图是否是欧拉回路或者欧拉通路.是的话如果一个点的度数除以2是奇数则可以产生一个XOR贡献值.之后如果是欧拉通路, 则答案是固定的,起点和终点需要多产生一次贡献值. 如果是欧拉回路, 则需要枚举起点. 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #inclu

POJ1300Door Man(欧拉回路)

Door Man Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2639   Accepted: 1071 Description You are a butler in a large mansion. This mansion has so many rooms that they are merely referred to by number (room 0, 1, 2, 3, etc...). Your mas

关于欧拉通路、欧拉回路的一些定理,推论

关于欧拉通路.欧拉回路的一些定义: 无向图:G是一个连通的无向图(1)经过G的每条边一次并且仅一次的路径为欧拉通路(起点和终点不一定要一样).(2)如果欧拉通路是回路(起点和终点是同一个),则为欧拉回路.(3)具有欧拉回路的无向图G称为欧拉图. 有向图:D是一个有向图,D的基图(把D的有向边改为无向边)是连通的(1)经过D的每条边一次并且仅一次的路径称为有向欧拉通路(起点和终点不一定一样).(2)如果有向欧拉通路是回路(起点和终点一样),那么称为有向欧拉通路.(3)具有有向欧拉通路的有向图D称为