Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 4531 | Accepted: 686 | Special Judge |
Description
Input
Output
Sample Input
1 02 2
1 2
3 43 6
1 2
1 3
2 4
3 5
4 6
5 64 12
1 2
1 3
1 4
2 5
2 6
3 7
3 8
4 8
4 7
5 6
5 7
6 80 0
Sample Output
1 2
4 2 3 1
1 6 3 2 5 4
1 6 7 2 3 4 5 8这是一个哈密尔顿回路的问题
小朋友之间有仇,不能坐一起,但是没仇的我们就可以坐一起
于是我们求反图,反图就是小朋友之间可以随便坐一起了。
要做成一个圈,其实就是一个哈密尔顿回路的问题了
这是满足哈密尔顿回路的充分条件,我们必须要让这个反图满足这个条件才能求解哈密尔顿回路,小朋友至多有n-1个仇人,那其余的就不是仇人,有n+1个,满足条件。
![]()
这个就是求解过程了。
#include
#include
#include
#include
using namespace std;
const int maxn = 410;
int a[maxn][maxn];
int res[maxn];
int used[maxn];
int start;
int end;
int n,m;
int top;
void Reverse(int s,int e) {
while(svoid expand() {
while(1) {
int flag=0;
for(int i=1; i<=n; i++) {
if(!used[i]&&a[end][i]) {
res[top++]=i;
end=i;
used[i]=1;
flag=1;
break;
}
}
if(!flag)
break;
}
}
void hamiltun() {
start=1;
for(int i=1; i<=n; i++) {
if(a[1][i]) {
end=i;
break;
}
}
used[start]=1;
used[end]=1;
res[0]=start;
res[1]=end;
top=2;
while(1) {
expand();
Reverse(0,top-1);
swap(start,end);
expand();
int mid=0;
if(!a[start][end]) {
for(int i=1; i2; i++) {
if(a[res[i]][end]&&a[res[i+1]][start]) {
mid=i+1;
break;
}
}
Reverse(mid,top-1);
end=res[top-1];
}
if(top==n)break;
for(int i=1; i<=n; i++) {
if(!used[i]) {
int j;
for(j=1; j1; j++)
if(a[res[j]][i]) {
mid=j;
break;
}
if(a[res[mid]][i]) {
end=i;
mid=j;
break;
}
}
}
start=res[mid-1];
Reverse(0,mid-1);
Reverse(mid,top-1);
res[top++]=end;
used[end]=1;
}
}
int main() {
while(scanf("%d%d",&n,&m)&&(n+m)) {
int u,v;
n<<=1;
//相同的点之间是不能为1
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
a[i][j]=(i^j);
memset(used,0,sizeof(used));
memset(res,0,sizeof(res));
top=0;
//在反图上求解
for(int i=1; i<=m; i++) {
scanf("%d%d",&u,&v);
a[u][v]=a[v][u]=0;
}
hamiltun();
cout<0];
for(int i=1; iprintf(" %d",res[i]);
cout<return 0;
}