ZOJ3332-競賽圖中的哈密頓路

競賽圖:圖中的任意兩點間有且僅有一條有向弧連接

求競賽圖中的哈密頓路的算法:

首先,由數學歸納法可證競賽圖在n>=2時必存在哈密頓路;

(1)n=2時顯然;

(2)假設n=k時,結論成立,哈密頓路爲V1,V2,...,Vi,...,Vk;

     現添加第k+1個結點,若存在弧<Vi,Vk+1>和弧<Vk+1,Vi+1>,則可得哈密頓迴路V1,V2,...,Vi,Vk+1,Vi+1,...,Vk;

     若不存在上述的vi,考慮到Vk+1與v1~vk的連通狀況,則只有下面種原哈密頓路的情況:

     1.所有的Vi(1<i<k)與Vk+1的弧的方向都是<Vi,Vk+1>,那麼可得哈密頓迴路V1,V2,...,Vi,...,Vk,Vk+1;

     2.所有的Vi(1<i<k)與Vk+1的弧的方向都是<Vk+1,Vi>,那麼可得哈密頓迴路Vk+1,V1,V2,...,Vi,...,Vk;

     3.存在一箇中間結點m,使得所有的Vi(1<=i<=m)與Vk+1的弧方向爲<Vk+1,Vi>,所有的Vj(m<j<=k)與Vk+1的弧的方向爲<Vj,Vk+1>,這時依然可以構造哈密頓路 V1,V2,...,Vi,...,Vk,Vk+1;

(3)那麼算法也顯然了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
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; i<n; i++)
    {
        printf("%d ",p1->x);
        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;
}



發佈了100 篇原創文章 · 獲贊 2 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章