10054
来源:互联网 发布:matlab之父编程实践 编辑:程序博客网 时间:2024/06/16 00:15
在图论中,连通图基于连通的概念。在一个无向图 G 中,若从顶点vi到顶点vj有路径相连(当然从vj到vi也一定有路径),则称vi和vj是连通的。如果 G 是有向图,那么连接vi和vj的路径中所有的边都必须同向。如果图中任意两点都是连通的,那么图被称作连通图。如果此图是有向图,则称为强连通图(注意:需要双向都有路径)。图的连通性是图的基本性质。
题意:给你n个珠子,一个珠子分为两半有两种颜色,用1到50来表示50种不同的颜色。把这些珠子串起来,两个紧挨着的珠子要满足一个条件就是接触的那部分颜色要相同
例如(1,2)(2,4),两个珠子的接触部分颜色相同都为2。当然,因为珠子最后是连成环的,第一个珠子和最后一个珠子也会接触,也要买满足这个条件
先输入T,有T组数据
输入n,有n个珠子
下面n行每行两个数字表示这个珠子的两个颜色,然后问你能不能连成一条链,能的话输出任意一种连接情况即可,不能的话输出失败
其本质是欧拉回路,欧拉回路的题只做过每背景的裸题,第一次做这个,想不到是欧拉回路,然后想了差不多一个小时才想到是欧拉回路,说说思考的思路
其实1到50代表50钟颜色也就是50个点,一个珠子的信息例如(1,2)其实就是一个无向边(1,2),注意是无向边,因为珠子是可以转过来的,(1,2)=(2,1),那么无疑就可以建立一个图了
另外,给你的n个珠子如果是能连成链的话,那么其实任意一个珠子都可以作为起点,最后要回到自己,然后就想到,那不就是在已有的图中进行遍历,遍历了所有的点然后回到自己吗?怎么那么像那么欧拉的………………然后再思考了一些细节,稍微推理了一下确定了就是要判断是否存在欧拉回路,若存在即输出路径
无向图的欧拉回路判断和路径输出
1.判断所有的点的度是否为偶数,如果有点不为偶数,则不存在欧拉回路
2.满足1的条件下,判断所给的图是否连通,不连通也不是欧拉回路
3.满足1和2的就是欧拉回路,然后dfs逆序输出路径,主要一定要逆序,不逆序是错的,后面会解释
经过有意的测试那先这道题是不需要判断图连通的,也就是所给数据图一定是连通的,所以直接判断度即可
#include <stdio.h>#include <string.h>#define N 55#define MAX 1010int g[N][N],vis[N];int d[N];int n;void euler(int u){ int v; for(v=1; v<=50; v++) if(g[u][v]) { g[u][v]--; g[v][u]--; euler(v); printf("%d %d\n",v,u); //一定要逆序输出 }}int main(){ int t,T; int i,j; int u,v; int count,max,start; scanf("%d",&T); for(t=1 ;t<=T; t++) { memset(g,0,sizeof(g)); memset(vis,0,sizeof(vis)); memset(d,0,sizeof(d)); scanf("%d",&n); for(i=1 ;i<=n; i++) { scanf("%d%d",&u,&v); d[u]++; d[v]++; g[u][v]++; g[v][u]++; } printf("Case #%d\n",t); //图是连通的,要判断所有点的度是否有为偶数 max=0; start=0; for(i=1 ;i<=50; i++) if( d[i]%2 ) break; if(i<=50) printf("some beads may be lost\n"); else //图连通而且所有点的度都为偶数,则是一个欧拉回路,输出路径 for(i=1; i<=50; i++) euler(i); if(t!=T) printf("\n"); } return 0;}
整个问题容易WA的地反是输出路径,其实就是一个dfs
for(i=1; i<=50; i++) euler(i);void euler(int u){ int v; for(v=1; v<=50; v++) if(g[u][v]) { g[u][v]--; g[v][u]--; euler(v); printf("%d %d\n",v,u); //一定要逆序输出,而且注意输出的边是(v,u)而不是(u,v) }}
如果写成这样是错的
void euler(int u){ int v; for(v=1; v<=50; v++) if(g[u][v]) { g[u][v]--; g[v][u]--;
printf("%d %d\n",u,v);
euler(v);
//这样相当于顺序输出 }}
在输入的时候使会有重边的,也就是g[i][j]的值不一定只是为1
然后从一个点出发,找到和他相连的点,然后删除这条无向边,所以是 g[u][v]--; g[v][u]--; 然后就去dfs下一个点v,最后在递归返回的时候才输出路径,也就是逆序输出,为什么要逆序输出了
因为和当前点i相连的点可能不止一个
例如当前点是1,上一条边是(3,1) . 而和1相连的点有2,7,11,能分成3个方向
往2的方向有:(1,2) (2,4)
往7的方向有:(1,7)(7,5)(5,6)
往11的方向有:(1,11)(11,12)(12,13)
如果顺序输出将会是
3 1
1 2
2 4
1 7
7 5
5 6
1 11
11 12
12 13
当找到起点之后,将起点压入栈中,然后访问与顶点相连的一个顶点,将该顶点压入栈中,同时删除这条边,然后继续DFS寻找顶点,并同样压栈、删除,最后,直到走到一个没有任何边与它相连的顶点(可能是起始点,也可能不是),便开始进行回溯,(回溯的同时进行弹栈,弹栈的结果也就是欧拉回路的逆序输出结果),回溯的过程就是寻找相连路径的过程,如果回溯的过程中发现仍然有边与当前顶点相连,那么继续从这个顶点沿着未删除的边去DFS,同时进行压栈等一系列操作,最后,必定会回到该点,然后继续回溯,直到顶点,逆序输出,结束
- 10054
- uva 10054
- Uva 10054
- UVA 10054
- uva 10054
- Socket 10054
- UVA 10054
- uva 10054
- UVA 10054
- 10054项链
- UVA 10054
- UVA 10054
- UDP 10054 解决办法!
- IOCP中10054错误
- recvfrom error 10054
- udp 10054错误修正
- uva 10054 - The Necklace
- 10054 - The Necklace(***)
- LeetCode-521. Longest Uncommon Subsequence I
- LeetCode-551. Student Attendance Record I
- LeetCode- 125. Valid Palindrome
- 环境变量
- 指针与数组
- 10054
- TheBrain Pro 9(思维导图软件)下载 v9.0.205.0 Beta官方中文版
- Springboot中常见注解的使用
- 数据结构数组相关算法和螺旋,蛇形,拉丁矩阵的实现
- Sony Vegas Pro 12 v12.0.367中文版 64位/32位
- MainActivity.java(zhou3)
- 一道搜索好题
- 你知道用Woof创建的Linux吗?
- MenuInfo.java(zhou3)