POJ 1780 Code(欧拉通路)

输入n(1<=n<=6),输出长度为10^n + n -1 的字符串答案。

其中,字符串以每n个为一组,使得所有组都互不相同,且输出的字符串要求字典序最小。

显然a[01...(n-1)]和a[12...n]为相邻组,可以看做有一条边从结点a[01...(n-1)]到结点a[12...n]。

题目转化成求欧拉通路。如果以每组的值为结点,则有10^6个结点,10^7条边。会MLE。(此时其实是哈密顿通路?)

这里以每组的值为边的边权,而边的2个结点分别是前n-1位数和后n-1位数。这样点是10^5个,边是10^6。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;

#define MP make_pair
#define ll long long
#define inf 0x3f3f3f3f
#define maxn 100010
#define maxm 1000010
int ten[]={1,10,100,1000,10000,100000,1000000};
struct Edge{
	int v,nxt;
	bool vis;
}e[maxm];
int head[maxn],esz;
void init(){esz=0;memset(head,-1,sizeof(head));}
void addedge(int u,int v){
	e[esz].v=v,e[esz].nxt=head[u];
	e[esz].vis=false;
	head[u]=esz++;
}
int st[maxm],top;
int ans[maxm];
int main(){
	//freopen("out","w",stdout);
	int n,m;
	while(~scanf("%d",&n) && n){
		if(n==1){puts("0123456789");continue;}
		init();
		for(int i=0;i<ten[n-1];++i){
			int x = i%ten[n-2];
			for(int j=9;j>=0;--j){
				addedge(i,x*10+j);
			}
		}
		top=0;
		int sz=0;
		st[top++]=0;
		while(top){
			int u = st[--top];
			bool f=false;
			for(int i=head[u];i!=-1;i=e[i].nxt){
				int v = e[i].v;
				if(e[i].vis) continue;
				e[i].vis = true;
				st[top++]=u;
				st[top++]=v;
				f=true;
				break;
			}
			if(f==false) ans[sz++]=u;
		}
		for(int i=0;i<n-2;++i) ans[sz++]=0;
		//for(int i=sz-1;i>=0;--i) printf("%d ",ans[i]); puts("");
		for(int i=sz-1;i>=0;--i) printf("%d",ans[i]%10);
		puts("");
	}
    return 0;
}
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;

#define MP make_pair
#define ll long long
#define inf 0x3f3f3f3f
#define maxn 100010
#define maxm 1000010
int ten[]={1,10,100,1000,10000,100000,1000000};
struct Edge{
	int v,nxt;
	int w;
}e[maxm];
int head[maxn],esz;
void init(){esz=0;memset(head,-1,sizeof(head));}
void addedge(int u,int v,int w){
	e[esz].v=v,e[esz].w=w,e[esz].nxt=head[u];
	head[u]=esz++;
}
int st[maxm],top;
int ans[maxm];
bool vis[maxm];
int main(){
	//freopen("out","w",stdout);
	int n,m;
	while(~scanf("%d",&n) && n){
		if(n==1){puts("0123456789");continue;}
		init();
		for(int i=0;i<ten[n-1];++i){
			int x = i%ten[n-2];
			for(int j=9;j>=0;--j){
				addedge(i,x*10+j,i*10+j);
			}
		}
		top=0;
		int sz=0;
		st[top++]=0;
		memset(vis,false,sizeof(vis));
		vis[0]=true;
		while(top){
			int u = st[--top];
			bool f=false;
			for(int i=head[u];i!=-1;i=e[i].nxt){
				int v = e[i].v;
				if(vis[e[i].w]) continue;
				vis[e[i].w]=true;
				st[top++]=u;
				st[top++]=v;
				f=true;
				break;
			}
			if(f==false) ans[sz++]=u;
		}
		for(int i=0;i<n-1;++i) ans[sz++]=0;
		//for(int i=sz-1;i>=0;--i) printf("%d ",ans[i]); puts("");
		for(int i=sz-1;i>=0;--i) printf("%d",ans[i]%10);
		puts("");
	}
    return 0;
}
时间: 2024-10-09 22:12:00

POJ 1780 Code(欧拉通路)的相关文章

poj 2513 Colored Sticks(欧拉通路+并查集+字典树)

题目链接:poj 2513 Colored Sticks 题目大意:有N个木棍,每根木棍两端被涂上颜色,现在给定每个木棍两端的颜色,不同木棍之间拼接需要颜色相同的 端才可以,问最后能否将N个木棍拼接在一起. 解题思路:欧拉通路+并查集+字典树.欧拉通路,每个节点的统计度,度为奇数的点不能超过2个.并查集,判断节点 是否完全联通.字典树,映射颜色. #include <cstdio> #include <cstring> #include <string> #includ

POJ 1386 Play on Words(有向欧拉通路 连通图)

题意  见下方中文翻译 每一个单词能够看成首尾两个字母相连的一条边  然后就是输入m条边  推断是否能构成有向欧拉通路了 有向图存在欧拉通路的充要条件: 1. 有向图的基图连通: 2. 全部点的出度和入度相等  或者  仅仅有两个入度和出度不相等的点  且这两点入度与出度的差一个为-1(起点)一个为1(终点). 推断是否连通就是应用并查集了 #include<cstdio> #include<cstring> using namespace std; const int N = 3

POJ 2513 无向欧拉通路+字典树+并查集

题目大意: 有一堆头尾均有颜色的木条,要让它们拼接在一起,拼接处颜色要保证相同,问是否能够实现 这道题我一开始利用map<string,int>来对颜色进行赋值,好进行后面的并查操作以及欧拉通路的判断,但是map效率太低,超时了 网上看了一遍发现必须得用效率更高的字典树对每个不同的颜色进行赋值 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace st

POJ--1386--Play on Words【判断有向图欧拉通路、欧拉回路】

链接:http://poj.org/problem?id=1386 题意:要开启一扇门,n个单词是密码,n个单词中,如果一个单词的首字母和前一个单词的尾字母相同,并且每个单词都能这么连起来且只用一次,则门可以开启,否则不能开启,现给出单词,判断门是否可以开. 有向图欧拉通路充要条件:D为有向图,D的基图连通,并且所有顶点的出度与入度都相等:或者除两个顶点外,其余顶点的出度与入度都相等,而这两个顶点中一个顶点的出度与入度之差为1,另一个顶点的出度与入度之差为-1. 有向图欧拉回路充要条件:当D的所

HDU 5883 F - The Best Path 欧拉通路 &amp; 欧拉回路

给定一个图,要求选一个点作为起点,然后经过每条边一次,然后把访问过的点异或起来(访问一次就异或一次),然后求最大值. 首先为什么会有最大值这样的分类?就是因为你开始点选择不同,欧拉回路的结果不同,因为是回路,所以你的开始点就会被访问多一次,所以如果是欧拉回路的话,还需要O(n)扫一次,枚举每个点作为起点. 欧拉通路的话,结果是固定的,因为只能从奇数度小的那个点作为起点,奇数度大的那个点作为终点. 关于点的访问次数:anstime  = Degree[i] / 2; //如果是奇数的,还要加上一.

关于欧拉通路、欧拉回路的一些定理,推论

关于欧拉通路.欧拉回路的一些定义: 无向图:G是一个连通的无向图(1)经过G的每条边一次并且仅一次的路径为欧拉通路(起点和终点不一定要一样).(2)如果欧拉通路是回路(起点和终点是同一个),则为欧拉回路.(3)具有欧拉回路的无向图G称为欧拉图. 有向图:D是一个有向图,D的基图(把D的有向边改为无向边)是连通的(1)经过D的每条边一次并且仅一次的路径称为有向欧拉通路(起点和终点不一定一样).(2)如果有向欧拉通路是回路(起点和终点一样),那么称为有向欧拉通路.(3)具有有向欧拉通路的有向图D称为

图论——欧拉通路、欧拉回路(有向图无向图混合图)

之前稍微了解有向图.无向图.混合图的欧拉通路.欧拉回路,这里做下笔记,以便日后翻阅. 无向图: 存在欧拉回路的条件:原图连通,每个结点均为偶度结点. 存在欧拉通路的条件:存在欧拉回路,或原图连通,有两个结点为奇度结点,其他结点均为偶度结点. 有向图: 存在欧拉回路的条件:基图连通,每个结点的入度等于出度. 存在欧拉通路的条件:存在欧拉回路,或基图连通,有一个结点入度等于出度+1,有一个结点出度等于入度+1,其他结点的入度等于出度. 混合图: 存在欧拉回路的条件: 1.将无向边随便定向,每个结点的

POJ - 1780 Code (欧拉回路+手写DFS)

Description KEY Inc., the leading company in security hardware, has developed a new kind of safe. To unlock it, you don't need a key but you are required to enter the correct n-digit code on a keypad (as if this were something new!). There are severa

POJ2513Colored Sticks(欧拉通路)(字典树)(并查集)

Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 35612   Accepted: 9324 Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a st

poj2513Colored Sticks(欧拉通路+字典树+并查集)

Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color? Input Input is a