【训练题】无序字母对 P1675

Description

给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。


Input

第一行输入一个正整数n.以下n行每行两个字母,表示这两个字母需要相邻。


Output

输出满足要求的字符串。如果没有满足要求的字符串,请输出“No Solution”。如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案。


Hint

不同的无序字母对个数有限,n的规模可以通过计算得到


Solution

这道题需要计算一条欧拉路径,无序所以是无向图,由于数据规模较大用邻接矩阵来存会爆RE所以这个无向图只能用用vector来存,存的是char字符和每条边的id。字典序需要最小所以输入所有路径后需要将g从小到大进行排序。然后vector一个ep序列记录欧拉路径树的后序遍历结果,这里有一个需要注意的地方详见注意事项。


判断无解就需要记录每个结点的度,如果不等于0和2(即不是欧拉回路或者欧拉路),那么就直接输出无解后retrun 0。如果满足条件,因为字典序要最小所以要找到第一个最小的奇点,并且将start更新成它。如果没有奇点那么在init中已经将start更新成字典序最小的结点作为路径的开端了。然后就是欧拉路径dfs。


注意事项:

1.因为vector是从0位置开始输入并且size()返回的是+1的大小所以循环的时候从0开始且结束循环不用取等。
2.输入的时候不要用getchar()因为getchar会把回车输进去所以用一个str数组存字符串然后使起点和终点等于str[0]和str[1]。
3.存的是无向图所以一条边id要一样。
4.排序的时候循环是从字符'A'到'z',不是从1到n。
5.输出的时候将后序遍历结果倒着输出,同样需要注意size()不取等,结束在0位置。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#define maxn 100005
using namespace std;
struct edge{
	char v;
	int id;
};
char x,y,start;
int n,cnt;
char str[5];
int num[maxn];
bool vis[maxn];
vector<edge>g[maxn];
vector<char>ep;
bool cmp(edge x,edge y){
	return x.v<y.v;
}
void init(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%s",str);
		x=str[0];
		y=str[1];
		if(i==1)start=x;
		if(start>x)start=x;
		if(start>y)start=y;
		g[x].push_back((edge){y,i});
		g[y].push_back((edge){x,i});
		num[x]++;
		num[y]++;
	}
	for(int i='A';i<='z';i++)
	sort(g[i].begin(),g[i].end(),cmp);
}
void find_circle(char x){
	for(int k=0;k<g[x].size();k++){
		char j=g[x][k].v;
		int id=g[x][k].id;
		if(vis[id])continue;
		else vis[id]=true;
		find_circle(j);
	}
	ep.push_back(x);
}
int main(){
	init();
	for(char i='A';i<='z';i++){
		if(num[i]%2==1){
			cnt++;
		}
	}
	if(cnt!=0&&cnt!=2){
		printf("No Solution\n");
		return 0;
	}
	if(cnt==2){
		for(int i='A';i<='z';i++){
			if(num[i]&1){
				start=i;
				break;
			}
		}
	}
	find_circle(start);
	for(int p=ep.size()-1;p>=0;p--){
		printf("%c",ep[p]);
	}
	putchar('\n');
	return 0;
}
posted @ 2018-11-30 16:33  虚拟北方virtual_north。  阅读(155)  评论(0编辑  收藏  举报