关于欧拉路径 汉密尔顿路径
欧拉路:
如果给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,这条路称为欧拉路;
如果给定无孤立结点图G,若存在一条回路,经过图中每边一次且仅一次,那么该回路称为欧拉回路。
存在欧拉回路的图,称为欧拉图。
一、 对于无向图G,具有一条欧拉路,当且仅当G是连通的,且有零个或两个奇数度结点。
且有零个奇数度结点,存在欧拉回路;有两个奇数度结点,存在欧拉路。
判断无向图G是否连通,可以从任意结点出发,进行深度优先遍历,如果可以遍历到所有点,
说明,图G连通,否则,图G不连通。
如HDU 1878 :http://acm.hdu.edu.cn/showproblem.php?pid=1878
#include <iostream> #include <fstream> using namespace std; ifstream fin("in.txt"); #define LEN 1001 bool visited[LEN]; bool arc[LEN][LEN]; int degree[LEN]; int n,m; void dfs(int v) //深度优先遍历 { visited[v]=true; for(int i=1;i<=n;i++) { if(!visited[i] && arc[v][i]) { dfs(i); } } } bool isConnected() //查看遍历后结果 { for(int i=1;i<=n;i++) { if(!visited[i]){return false;} } return true; } bool isCircuit() //通过度数是否为偶数判断欧拉回路 { for(int i=1;i<=n;i++) { if(degree[i]%2){return false;} } return true; } int main() { int i,p,q; while(1) { memset(visited,0,LEN); memset(arc,0,sizeof(bool)*LEN*LEN); memset(degree,0,sizeof(int)*LEN); fin>>n>>m; if(n==0)break; for(i=0;i<m;i++) { fin>>p>>q; degree[p]++;degree[q]++; arc[p][q]=arc[q][p]=true; } dfs(1); if(!isConnected()){cout<<0<<endl;} else{ if(isCircuit())cout<<1<<endl; else cout<<0<<endl; } } return 0; }
3 3 (顶点数 边数)
1 2 -->
1 3 --> 边的两个顶点
2 3 -->
3 2
1 2
2 3
0
二 、对于有向图G,具有一条单向欧拉路,当且仅当G是连通的,且每个结点入度等于出度,或者,
除两个结点外,每个结点的入度等于出度,而这两个结点满足,一个结点的入度比出度大1,
另一个结点的入度比出度小1。
判断有向图G是否连通,可以某一结点出发,进行深度优先遍历,如果存在一点作为初始结点
可以遍历到所有点,说明,图G连通,否则,图G不连通。
三、混合图(有的边是单向的,有的边是无向的。常被用于比喻城市里的交通网络,有的路是单行道,有的路是双行道。)
找到一个给每条无向的边定向的策略,使得每个顶点的入度等于出度,这样就能转换成上面第二种情况。这就可以转化成一个二部图最大匹配问题
汉密尔顿路
给定图G,若存在一条路,经过图中每个结点恰好一次,这条路称作汉密尔顿路。
给定图G,若存在一条回路,经过图中每个结点恰好一次,这条回路称作汉密尔顿回路。
具有汉密尔顿回路的图,称作汉密尔顿图。
定理 5.4.3 若图G=<V,E>具有汉密尔顿回路,则对于结点集V的每个非空子集S,均有W(G-S)<=|S|成立。
其中W(G-S)是G-S 的连通分支数,|S|表示集合S的元素数。
定理 5.4.4 设G是具有n个结点的简单图,如果G中每一对结点度数之和大于等于n-1,则在G中存在一条汉密尔顿路。
定理 5.4.5 设G是具有n个结点的简单图,如果G中每一对结点度数之和大于等于n,则在G中存在一条汉密尔顿回路。