caioj1230: [图论补充]哈密顿路径
保存模版
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int n,m,st,ed; int len,a[510]; bool v[510],mp[510][510]; void reverse(int l,int r) { while(l<r) { swap(a[l],a[r]); l++;r--; } } void expand() { while(1) { bool bk=false; for(int i=1;i<=n;i++) { if(v[i]==false&&mp[ed][i]==true) { v[i]=true;a[++len]=i;ed=i; bk=true;break; } } if(bk==false)break; } } void hamilton() { st=1; for(int i=1;i<=n;i++) if(mp[st][i]==true){ed=i;break;} v[st]=true;a[++len]=st; v[ed]=true;a[++len]=ed; while(1) { expand(); reverse(1,len);swap(st,ed); expand(); //若st,ed不相连,处理成相连 if(mp[st][ed]==false) { //在a[2]到a[len-1]中寻找两个相邻的且与st、ed同时相连的点(必存在) for(int i=2;i<len-1;i++) { if(mp[st][a[i+1]]==true&&mp[ed][a[i]]==true) { reverse(i+1,len);//倒置a[i+1]到a[len] ed=a[len];break; } } } if(len==n)return ; //若a元素不满n个,未被遍历过的点在a[]中寻找与其相连的点 for(int y=1;y<=n;y++) { if(v[y]==false) { bool bk=false; for(int i=1;i<len;i++) { if(mp[a[i]][y]==true)//相当于把a[i]~a[i+1]之间的连接断开,然后把a[i]和y连起来 { st=a[i+1];ed=y; reverse(1,i);reverse(i+1,len); v[y]=true;a[++len]=y; bk=true;break; } } if(bk==true)break; } } } } int main() { scanf("%d%d",&n,&m); int x,y; memset(mp,false,sizeof(mp)); for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); mp[x][y]=true;mp[y][x]=true; } len=0;memset(a,0,sizeof(a)); memset(v,false,sizeof(v)); hamilton(); for(int i=1;i<len;i++)printf("%d ",a[i]); printf("%d\n",a[len]); return 0; }
pain and happy in the cruel world.