首页 > 技术文章 > 欧拉路

lesning 2019-12-26 19:29 原文

https://ac.nowcoder.com/acm/contest/964/B

整了个例题

 

 

一、欧拉路(能把边只走一次全走完,图还得连通)

  1.无向图

     (1)度数全是偶数 

      (2)有两个奇数度数节点(图都有偶数个奇度数节点,或者没有奇数度数节点)。

     2.有向图

      (1)每个点出度和入度一样

      (2)出度入度差为1的点只有两个,差最大是1,且一个入度多,一个出度多(起点和终点)

就这样了

 

二 ,欧拉回路(回到出发点)

   1有向图(度数全是偶数 )

            2无向图(每个点出度和入度一样)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
int in[100];
int out[100];
int par[100];
int vis[100];
int find(int x){
	if(par[x] == -1) return x;
	return par[x] = find(par[x]);
}

int main(){
	int t;
	string sn;
	cin>>t;
	while(t--){
		int n;
		memset(vis,0,sizeof(vis));
		memset(par,-1,sizeof(par));
		memset(in,0,sizeof(in));
		memset(out,0,sizeof(out));
		cin>>n;
		for(int i=0;i<n;i++){
			cin>>sn;
			int be = sn[0] - 'a';
			int en = sn[sn.length() - 1] - 'a';
			in[be]++;
			out[en]++;
			vis[be] = 1 ;
			vis[en] = 1;
			int a = find(be);
			int b = find(en);
			if(a!= b){
				par[a] = b;
			}
		}
		
		int cnt=0;
		int s = 0;//七点 
		int cn = 0;//终点 
		int flag = 0;
		
		for(int i=0;i<= 30;i++){
			if(vis[i]){
				if(find(i) == i) cnt++;
				
				if(in[i] == out[i] + 1) cn++;
				else if(out[i] == in[i] + 1) s++;
				else if(abs(in[i] - out[i]) > 1) flag  = 1;
			}
		}
		if(cnt == 1 && flag == 0){
			if(s == 1 && cn == 1){
				printf("Ordering is possible.\n");
			}
			else if(s == 0 && cn == 0){
				printf("Ordering is possible.\n");
			}
			else{
				printf("The door cannot be opened.\n");
			}
		}
		else{
			printf("The door cannot be opened.\n");
		}
	}
	
	return 0;
}
 

 

  

推荐阅读