其他分享
首页 > 其他分享> > uva 1030 欧拉回路

uva 1030 欧拉回路

作者:互联网

欧拉回路

无向图 有向图
欧拉回路 所有点均为偶度顶点(顶点度数为偶数) 所有点出度=入度(入度=箭头射入个数)
欧拉通路 最多仅2个点为奇度顶点(顶点度数为奇数) 最多两个点出度!=入度;其中一个出度比入度大1;另一个入度比出度大1

uva 1030

除了起点和终点以外,其他的点“进出”次数相等。

即一个无向图是连通的,且最多只有两个奇点,一定存在欧拉回路

// 坑:为一个环状时 形成欧拉回路tmp为26
//
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int G[30][30];// 26 个小写字母 
int vis[26];
int out[26];
int in[26];
void dfs(int u){  // u 
	vis[u]= 1; // 标记起始量已访问 
	for(int v=0;v<26;v++){ 
		if((G[u][v]||G[v][u])&&vis[v]==0){
			dfs(v);
		}
	}
	return ;
}
// 判断是否无向图联通 思路:
//先访问存在的点 
bool iscircle(){
	int tmp=0;
	for(int i=0;i<26;i++)
	for(int j=0;j<26;j++){
	
		if(G[i][j]){
			if(tmp==0) {
				dfs(i);
				tmp=1;
			} else{
				if(!vis[i]||!vis[j]) //如果点i或者j未被访问 
				return false;
			}
		}
	
	} 
		return true;
} 

// 判断是否无向图联通 思路:
//先访问存在的点  
int main(){
	//1.处理输入输出 输入为有向图 
	//2.判断无向图联通
	//3. 判断入度数和出度是否相同 最多两个不同 
	char c[1005];
//	freopen("10129.txt","r",stdin);
	int t;
	cin>>t;
	while(t--){
		memset(G,0,sizeof(G));
		int n;
		cin>>n;
		memset(out,0,sizeof(out));
		memset(in,0,sizeof(in));
		memset(vis,0,sizeof(vis)) ;
		for(int i=0;i<n;i++){
			scanf("%s",c);
			int v=c[strlen(c)-1]-'a';
			int u=c[0]-'a';
			G[u][v] ++;
			out[v]++;
			in[u]++;
		}
		int tmp1=0,tmp2=0,tmp=0;
		// tmp1  出度比入度大一 
		// tmp2 入度比出度大一 
		//	tmp 为入度等于出度的个数 
		for(int i =0;i<26;i++){
			if(out[i]==in[i])
				tmp ++; 
			if(out[i]==in[i]+1){// 出度比入度大一 
				tmp1++;	
			}else if(out[i]+1==in[i]){//  入度比出度大一 
				tmp2++; 
			}
		} 
		if((tmp==26-2&&tmp1==1&&tmp2==1)||tmp==26&&iscircle()){   // 要考虑成环的情况 
			cout<<"Ordering is possible.\n"; 
		}else{
			cout<<"The door cannot be opened.\n";
		}	
	}
	
	return 0;
} 

//另一种思路通过读入度 来判断连通性 
// 上面通过双向判断dfs联通G[u][v] 和G[v][u] 
void dfs(int u){  // u 
	vis[u]= 1; // 标记起始量已访问 
	for(int v=0;v<26;v++){ 
		if(G[u][v]&&vis[v]==0){
			dfs(v);
		}
	}
	return ;
}	
for(int j=0;j<26;j++)
    if(in[j]){
        dfs(j);break;
    }
int flag2=1;
for(int i=0;i<26;i++)
{
    if(in[i]&&!vis[i]){
        flag2=0;break;
    } 
    if(out[i]&&!vis[i]){
        flag2=0;break;
    }
}
//
if((tmp==26-2&&tmp1==1&&tmp2==1)||tmp==26&&flag2==1){
    cout<<"Ordering is possible.\n"; 
}else{
    cout<<"The door cannot be opened.\n";
}	

标签:26,int,出度,memset,vis,uva,1030,欧拉
来源: https://www.cnblogs.com/chichina/p/12668886.html