码迷,mamicode.com
首页 > 其他好文 > 详细

SGU 101 题解

时间:2016-07-24 11:56:02      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:

#include<iostream>
#include<algorithm>
using namespace std;
struct sticktype
{
	int l;
	int r;
	bool vis;
}stick[101];
struct pointtype
{
	int amount;
	int next[7];
	bool vis; 
}point[7];
int tail=0;
int queue[201];
void dfs(int p);
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<=6;i++)
	{
		point[i].amount=0;
		for(int j=0;j<=6;j++)
		{
			point[i].next[j]=0;
		}
	}
	for(int i=1;i<=n;i++)
	{
		cin>>stick[i].l>>stick[i].r;
		stick[i].vis=false;
		point[stick[i].l].vis=false;
		point[stick[i].r].vis=false;
		point[stick[i].l].amount++;
		point[stick[i].l].next[stick[i].r]+=1;
		point[stick[i].r].amount++;
		point[stick[i].r].next[stick[i].l]+=1;
	}
	int m=0;
	int res=0;
	for(int i=0;i<=6;i++)
	{
		if(point[i].amount!=0)
		{
			m++;
			if(point[i].amount%2!=0)
			{
				res++;
			}
		}
	}
	if(res!=0&&res!=2)
	{
		cout<<"No solution";
		return 0;
	}
	int begin;
	if(res==0)
	{
		for(int i=0;i<=6;i++)
		{
			if(point[i].amount!=0)
			{
				begin=i;
				break;
			}
		}
	}
	else
	{
		for(int i=0;i<=6;i++)
		{
			if(point[i].amount%2!=0)
			{
				begin=i;
				break;
			}
		}
	}
	dfs(begin);
	for(int i=0;i<=6;i++)
	{
		if(!point[i].vis&&point[i].amount!=0)
		{
			cout<<"No solution";
			return 0;
		}
	}
	for(int i=tail;i>=2;i--)
	{
		for(int j=1;j<=n;j++)
		{
			if(!stick[j].vis)
			{
				if(stick[j].l==queue[i-1]&&stick[j].r==queue[i])
				{
					stick[j].vis=true;
					cout<<j<<" -"<<endl;
					break;
				}
				if(stick[j].r==queue[i-1]&&stick[j].l==queue[i])
				{
					stick[j].vis=true;
					cout<<j<<" +"<<endl;
					break;
				}
			}	
		}
	}
	return 0;
}
bool check(int p)
{
	for(int i=0;i<=6;i++)
	{
		if(point[p].next[i])
		{
			return false;
		}
	}
	return true;
}
void dfs(int p)
{
	point[p].vis=true;
	for(int i=0;i<=6;i++)
	{
		while(point[p].next[i])
		{
			point[p].next[i]--;
			int next_point=i;
			point[next_point].next[p]--;
			dfs(next_point);
		}
	}
	if(check(p))
	{
		tail++;
		queue[tail]=p;
	}
	return;
}

  SGU 101 为欧拉路径问题

欧拉路径定义是图上的一条路径,满足经过每一条边正好一次

欧拉路径在无向图存在欧拉路径的充要条件是度为奇数的顶点数为0或2且图为连通图

算法细节如下:

读入边的数据,用sticktype存储,用vis标记解决输出时候的重复问题

对于每一条边看做无向边,对于每一个顶点,其相邻顶点用next数组标记,因为顶点数少,且出现重边情况,所以用计数方法存储,amount存储顶点的度,vis标记用于判断图的连通性

判断特殊情况后,深搜遍历边,对于当前搜索到的顶点,枚举每一条与之相邻的边,将该边删除,并搜索该边的另一个顶点,如果相邻的边都被遍历过,将该顶点放入队列并回溯。

搜索完成后,生成的队列为欧拉路径的逆序,根据序列找到相应的边,判断方向,输出即可

一定要注意判断图的连通性,我为这个卡了一整天!!!

SGU 101 题解

标签:

原文地址:http://www.cnblogs.com/shao0099876/p/5700276.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!