列表

详情


NC21304. 汉密尔顿路径

描述

有一个有向图,恰好有n*(n-1)/2条边,对于每一个(i,j)要么有一条
i->j的边,要么有一条j->i的边,但不会同时存在这两条边
给你这个图的邻接矩阵a,a[i][j]='+'表示i->j有边,'-'表示没有
a[i][i]='.'表示这个图没有自环
图的汉密尔顿路径是长度为n包含每个点恰好一次的路径
实际上对于上面这种特性的图,一定存在至少一条汉密尔顿路径
输出任意一条汉密尔顿路径

输入描述

第一行输入一个整数n (2 ≤ n ≤ 100)
接下来n行每行输入一个长度为n的字符串

输出描述

输出一行包含n个整数

示例1

输入:

2
.+
-.

输出:

0 1

示例2

输入:

3
.++
-.+
--.

输出:

0 1 2

示例3

输入:

4
.--+
+.+-
+-.-
-++.

输出:

3 1 2 0

示例4

输入:

4
.+-+
-.+-
+-.-
-++.

输出:

3 2 0 1

示例5

输入:

5
.++--
-.-++
-+.+-
+--.+
+-+-.

输出:

3 0 2 1 4

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Java 解法, 执行用时: 66ms, 内存消耗: 11832K, 提交时间: 2023-04-16 16:31:57

import java.util.*;

/**
 * description:
 * 汉密尔顿路径
 * @author czs
 * @create 2023-04-16 14:36
 */
public class Main {
static int n;
    static char[][] map;
    static boolean[] visited;
    static int[] res;
    static int[] out;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        n = Integer.parseInt(in.nextLine());
        map = new char[n][n];
        out = new int[n+1];
        for (int i = 0; i < n; i++) {
           map[i] = in.nextLine().toCharArray();
            for (int j = 0; j < n; j++) {
                if(map[i][j] == '+') out[i]++;
            }
        }
        visited = new boolean[n];
        res = new int[n];
        int maxIndex = n;
        out[maxIndex] = -1;
        for (int i = 0; i < n; i++) {
            maxIndex = findMax(maxIndex);
            visited[maxIndex] = true;
            res[i] = maxIndex;
            for (int j = 0; j < n; j++) {
                if(map[j][maxIndex] == '+') out[j]--;
            }
        }
        for (int i = 0; i < n; i++) {
            System.out.print(res[i]);
            if(i!=n-1){
                System.out.print(" ");
            }
        }
        in.close();
    }

    private static int findMax(int k) {
        int maxOut = -1;
        int maxIndex = -1;
        for (int i = 0; i < n; i++) {
            if( (k==n || map[k][i] == '+') && out[i]>maxOut && !visited[i]){
                maxOut = out[i];
                maxIndex = i;
            }
        }
        return maxIndex;
    }
}

C++14(g++5.4) 解法, 执行用时: 5ms, 内存消耗: 488K, 提交时间: 2019-12-31 17:40:25

#include<bits/stdc++.h>
using namespace std;
const int N=105;
char mp[N][N];
int main() {
    int n;scanf("%d",&n);
    for(int i=0; i<n; ++i)scanf("%s",mp[i]);
    list<int> path;
    for(int i=0; i<n; ++i) {
        auto it=path.begin();
        while(it!=path.end())
            if(mp[i][*it]=='+')break;
            else ++it;
        path.insert(it,i);
    }
    for(int x:path)printf("%d ",x);
    return 0;
}

C++(clang++11) 解法, 执行用时: 8ms, 内存消耗: 508K, 提交时间: 2021-03-01 22:17:38

#include<bits/stdc++.h>
using namespace std;
const int N=105;
char mp[N][N];
int main() {
    int n;scanf("%d",&n);
    for(int i=0; i<n; ++i)scanf("%s",mp[i]);
    list<int> path;
    for(int i=0; i<n; ++i) {
        auto it=path.begin();
        while(it!=path.end())
            if(mp[i][*it]=='+')break;
            else ++it;
        path.insert(it,i);
    }
    for(int x:path)printf("%d ",x);
    return 0;
}

上一题