您的位置:首页 > 其它

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

2014-12-08 19:46 441 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: