junior19

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Tour Route

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 759    Accepted Submission(s): 153
Special Judge


Problem Description
The city is so crowded that the mayor can't bear any longer. He issued an order to change all the roads into one-way street. The news is terrible for Jack, who is the director of a tourism company, because he has to change the travel route. All tourists want to set out from one scenic spot, then go to every scenic spots once and only once and finally return to the starting spot. They don’t care about which spot to start from, but they won’t go back to the starting spot before they have visited all other spots. Fortunately, the roads in the city have been perfectly built and any two scenic spots have been connected by ONE road directly. Jack gives the map of the city to you, and your task is to arrange a new travel route around the city which can satisfy the tourists.
 

Input
Input consists of multiple test cases and ends with a line of “0”.
For each test case:
The first line contains a single integer n (0<n<=1000), representing the number of city scenic spots. Scenic spots are numbered form 1 to n.
Then n lines follows, and each line consists of n integers. These n lines make a matrix. If the element in the ith row and the jth column is 1(i≠j), it means that the direction of the road between spot i and spot j is from spot i to spot j. If that element is 0, it means that the road’s direction is from spot j to spot i. The numbers in the main diagonal of the matrix are all 0. (i and j start from 1)
 

Output
For each test case, print all the spots No. according to the traveling order of the route in one line. If multiple routes exist, just print one of them. If no such route exists, print a “-1” instead. Because the starting spot is the same as the ending spot, so you don’t need to print the ending spot.

This problem needs special judge.
 

Sample Input
5 0 0 1 1 1 1 0 1 1 0 0 0 0 1 0 0 0 0 0 1 0 1 1 0 0 2 0 1 0 0 0
 

Sample Output
1 3 4 5 2 -1
 

Source
题意:给出一个n阶竞赛图(每对顶点间都有边相连的有向图),找出一个哈密尔顿回路(经过所有节点,且每个点只经过一次),没有就输出-1。

思路:竞赛图(n != 2)一定存在哈密尔顿路径,但回路就不一定了,需要遍历每个点,构建一次哈密尔顿路径,再判断首尾是否相连。

# include <iostream>
# include <cstdio>
# include <cstring>
# define maxn 1000
using namespace std;
int n, nex[maxn+3], map[maxn+3][maxn+3];
bool expend(int s)
{
    memset(nex, -1, sizeof(nex));
    int head = s, tail = s;
    for(int i=0; i<n; ++i)
    {
        if(i==s) continue;
        if(map[i][head])//直接插入。
        {
            nex[i] = head;
            head = i;
        }
        else//找到合适的位置插入。
        {
            int x = head, y = nex[head];
            while(y != -1 && map[y][i])
            {
                x = y;
                y = nex[y];
            }
            nex[x] = i;
            nex[i] = y;
            if(y == -1)
                tail = i;
        }
    }
    if(map[tail][head])
    {
        nex[tail] = head;
        return true;
    }
    return false;
}

bool solve()
{
    for(int i=0; i<n; ++i)
        if(expend(i))
            return true;
    return false;
}

int main()
{
    while(~scanf("%d",&n),n)
    {
        for(int i=0; i<n; ++i)
            for(int j=0; j<n; ++j)
                scanf("%d",&map[i][j]);
        if(n==1)
            puts("1");
        else if(n==2 || !solve())
            puts("-1");
        else
            for(int i=0,j=0; i<n; ++i, j=nex[j])
                printf("%d%c",j+1,i==n-1?'\n':' ');
    }
    return 0;
}


posted on 2017-04-12 17:07  junior19  阅读(300)  评论(0编辑  收藏  举报