這是一個全新的概念,省賽上出現了這種題目,zoj 3332
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3332圖中任意兩點,至少存在一條有向邊,構成一個哈密頓(好像和 哈密爾頓 不同)路;
對于一條以構建的哈密頓路的n個點(第1個點到第n個點,注意 第i個點 不一定是 點i ,eg,1 - 4 - 2 - 3,第2個點為4,第3個點為2,第4個點為3),
插入第n+1個點,肯定找到一條有向路與之相連
這里分3種情況
1> 第n + 1個點 與第一個點相連,使第n + 1個點成為第一個點
2> 最后一個點與第n+1個點相連,使第n + 1個點成為最后一個點
3> 能在原哈密頓路中找到一個相連的點 ,第i個點 和 第i+1個點 使得 (第i個點與第n+1個點 且 第n+1個點與第i+1個點)相連,所以在第i個點與第i+1個點中插入第n+1個點,這是典型的鏈式操作;
因此,用STL里的list即可完成如上3步驟;
我只是略懂略懂,不足之處,請指教,并附上代碼
#include <iostream>
#define M 101
#include <list>
using namespace std;
bool f[ M ][ M ];
bool flag;
list <int> L;
list <int>::iterator it , pre;


void init (int n)
{
for (int i = 1;i <= n;++ i)
for (int j = 1;j <= n;++ j)
f[ i ][ j ] = false;
}


void solve (int n)
{
int i;
L.push_back(1);

for (i = 2;i <= n;++ i)
{
it = L.begin ();


if (f[ i ][ *it ])
{
L.push_front(i);
continue;
}

it = L.end();
-- it;


if (f[ *it ][ i ])
{
L.push_back(i);
continue;
}

it = pre = L.begin();
++ it;

while (it != L.end())
{

if (f[ *pre ][ i ] && f[ i ][ *it ])
{
L.insert(it , i);
break;
}
pre ++;
it ++;
}
}
}


int main()
{
int t , n , i , k , g;
int a , b;
scanf ("%d" , &t);

while (t --)
{
L.clear();
scanf ("%d" , &n);
k = n * (n - 1) / 2;
init (n);
flag = true;

for (i = 1;i <= k;++ i)
{
scanf ("%d %d" , &a , &b);
f[ a ][ b ] = true;
}
solve (n);


if (L.size() != n)
{
puts ("Impossible");
continue;
}


for (it = L.begin(); it != L.end();++ it)
{
if (it != L.begin()) printf (" ");
printf ("%d" , * it);
}
printf ("\n");
}
return 0;
}