竞赛图:图中的任意两点间有且仅有一条有向弧连接
求竞赛图中的哈密顿路的算法:
首先,由数学归纳法可证竞赛图在n>=2时必存在哈密顿路;
(1)n=2时显然;
(2)假设n=k时,结论成立,哈密顿路为V1,V2,...,Vi,...,Vk;
现添加第k+1个结点,若存在弧
若不存在上述的vi,考虑到Vk+1与v1~vk的连通状况,则只有下面种原哈密顿路的情况:
1.所有的Vi(1,那么可得哈密顿回路V1,V2,...,Vi,...,Vk,Vk+1;
2.所有的Vi(1,那么可得哈密顿回路Vk+1,V1,V2,...,Vi,...,Vk;
3.存在一个中间结点m,使得所有的Vi(1<=i<=m)与Vk+1的弧方向为
(3)那么算法也显然了。
#include
#include
#include
#include
#include
using namespace std;
const int NN=110;
int n,map[NN][NN];
struct node
{
int x;
struct node *next;
}*h;
inline void clr(node *p)
{
node *pp;
while (p)
{
pp=p;
p=p->next;
delete(pp);
}
}
inline bool ok(int i,int j,int k)
{
return (map[i][j] && map[j][k]);
}
void solve()
{
node *p1,*p2;
clr(h);
h=new node;
h->x=0;
h->next=NULL;
for (int i=1; i<=n; i++)
{
p1=h;
while (p1->next && !ok(p1->x,i,p1->next->x)) p1=p1->next;
p2=new node;
p2->x=i;
p2->next=p1->next;
p1->next=p2;
}
p1=h->next;
for (int i=1; ix);
p1=p1->next;
}
printf("%d\n",p1->x);
}
int main()
{
int cas,u,v;
scanf("%d",&cas);
while (cas--)
{
scanf("%d",&n);
if (n==1)
{
printf("1\n");
continue;
}
for (int i=1; i<=n; i++) map[0][i]=true;
for (int i=1; i<=n*(n-1)/2; i++)
{
scanf("%d%d",&u,&v);
map[u][v]=true;
map[v][u]=false;
}
solve();
}
return 0;
}