SGU 101 Domino(无向图的欧拉路径)

http://acm.sgu.ru/problem.php?contest=0&problem=101


本题即寻找无向图的欧拉路径

无向图存在欧拉路径的条件:1.连通图:用并查集即可判断

    2.所有点的度数均为偶数或仅有两个点的度数为奇数

AC代码:

#include <vector>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>

using namespace std;

const int MAX = 110;

typedef pair <int, int> Pii;
int a[MAX],b[MAX],vis[MAX];
int v[10],father[10];
vector <Pii> vt[10];
vector <Pii> path;

void Init(){///并查集的初始化
	for(int i=0; i<=6; i++)
		father[i] = i;
}

int Find(int x){///并查集的查询
	if(x != father[x])
		father[x] = Find(father[x]);
	return father[x];
}

bool check(){//!判断是否是欧拉路径
	for(int i=0; i<=6; i++)///是否连通
		if(v[i])
			if(Find(i) != Find(a[0]))
				return false;
	int cnt = 0;
	for(int i=0; i<=6; i++)
		if(vt[i].size() % 2)	cnt++;
	if(cnt == 0 || cnt == 2)///度数要求
		return true;
	return false;
}

void DFS(int u){///记录路径
	for(int i=0; i<vt[u].size(); i++){
		if(vis[vt[u][i].first])	continue;
		vis[vt[u][i].first] = 1;
		DFS(vt[u][i].second);
		path.push_back(Pii(vt[u][i].first + 1, b[vt[u][i].first] == u));
	}
}

int main(){
	//freopen("in.txt", "r", stdin);
	int n;
	Init();
	scanf("%d",&n);
	for(int i=0; i<n; i++){
		scanf("%d%d",&a[i],&b[i]);
		v[a[i]] = v[b[i]] = 1;
		father[Find(a[i])] = Find(b[i]);///并查集的合并
		vt[a[i]].push_back(Pii(i, b[i]));///邻接表存储无向图
		vt[b[i]].push_back(Pii(i, a[i]));
	}
	if(check() == false){
		cout << "No solution" << endl;
		return 0;
	}
	for(int i=0; i<=6; i++){
		if(vt[i].size() % 2){
			DFS(i);
			for(int j=path.size(); j>=1; j--){
				cout << path[j-1].first;
				if(path[j-1].second)	cout << " -";
				else	cout << " +";
				cout << endl;
			}
			return 0;
		}
	}
	for(int i=0; i<=6; i++){
		if(vt[i].size()){
			DFS(i);
			for(int j=path.size(); j>=1; j--){
				cout << path[j-1].first;
				if(path[j-1].second)	cout << " -";
				else	cout << " +";
				cout << endl;
			}
			return 0;
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值