2020年团体程序设计天梯赛 L3-1 那就别担心了

思路:

题目标签是记忆化搜索,但是这种题我用的拓扑排序

首先建好图,将多余的边删掉,再从A点开始拓扑到B点,如果可以推到其他无出边的点,则不是逻辑自洽。路上记录边数即可求出A到B的条数。

Tip:

拓扑排序注意拓扑到B点就立刻停止,如果WA了测试点4极有可能是这种情况。

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn = 1000 + 5;
const int INF = 0x7FFFFFFF;

vector<int> chu[maxn];
int ru[maxn];
int cnt[maxn];

int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int x, y;
        cin >> x >> y;
        chu[x].push_back(y);
        ru[y]++;
    }
    int A, B;
    cin >> A >> B;

    queue<int> que2;
    for (int i = 0; i <= maxn; i++) {
        if (ru[i] == 0 && i != A)
            que2.push(i);
    }
    while (!que2.empty()) {
        int now = que2.front();
        que2.pop();
        for (auto i:chu[now]) {
            ru[i]--;
            if (ru[i] == 0 && i != A)
                que2.push(i);
        }
    }
    queue<int> que;
    que.push(A);
    cnt[A] = 1;
    bool flag1 = true;
    while (!que.empty()) {
        int now = que.front();
        que.pop();
        if (now == B)
            continue;
        if (chu[now].empty() && now != B)
            flag1 = false;
        for (auto i:chu[now]) {
            cnt[i] += cnt[now];
            ru[i]--;
            if (ru[i] == 0)
                que.push(i);
        }
    }
    cout << cnt[B] << " ";
    if (flag1)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
    return 0;
}

  

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