ACM 实验室2020.10.10天梯赛练习*2

7-15  球队“食物链”

题意:n个点m个关系,要求一个排列使得满足关系

思路:dfs+剪枝,注意两个剪枝点:

    1.如果有解第一个数一定是1

    2.dfs中如果剩下的点中没有能和1相连通的,就不用遍历了

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int maxn = 100 + 15;
const double eps = 1e-9;
int mp[maxn][maxn];

int n;
int vis[maxn];
bool findYes;
vector<int> v;

void dfs(int now) {
    bool flag = true;
    for (int i = 1; i <= n; i++)
        if (!vis[i]) {
            flag = false;
            break;
        }
    if (flag) {
        if (!mp[v[v.size() - 1]][v[0]]) {
            return;
        }
        for (int i = 0; i < v.size() - 1; i++)
            cout << v[i] << " ";
        cout << v[v.size() - 1] << endl;
        findYes = true;
        return;
    }
    bool yes = false;
    for (int i = 1; i <= n; i++)
        if (!vis[i] && mp[i][1]) {
            yes = true;
        }
    if (!yes)
        return;
    for (int i = 1; i <= n; i++) {
        if (!vis[i] && mp[now][i]) {
            vis[i] = true;
            v.push_back(i);
            dfs(i);
            if (findYes)
                return;
            v.pop_back();
            vis[i] = false;
        }
    }
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        string s;
        cin >> s;
        for (int j = 0; j < n; j++) {
            if (s[j] == 'W')
                mp[i][j + 1] = 1;
            else if (s[j] == 'L')
                mp[j + 1][i] = 1;
        }
    }
    vis[1] = true;
    v.push_back(1);
    dfs(1);
    if (!findYes)
        cout << "No Solution" << endl;
    return 0;
}

  

原文地址:https://www.cnblogs.com/Whiteying/p/13796458.html