首页 > 代码库 > POJ 1780 Code(欧拉通路)

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 1000010int 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 1000010int 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;}

 

POJ 1780 Code(欧拉通路)