为什么分别对每个邻接表排序是错的?
  • 板块P1127 词链
  • 楼主RyanLiUNMAKE
  • 当前回复1
  • 已保存回复1
  • 发布时间2025/7/27 14:37
  • 上次更新2025/7/27 19:54:35
查看原帖
为什么分别对每个邻接表排序是错的?
716556
RyanLiUNMAKE楼主2025/7/27 14:37

对于本题,为什么先建图然后分别对每个邻接表排序是错的,修改为对整个单词数组排序后再建图即可通过。

以下是代码,标记 new 的代码是正确解法,标记 old 的代码是对每个邻接表分别排序的错解。

#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
#include <bitset>
using namespace std;

const int N = 1010, M = 30, LIM = 26;
int n, from, to, ind[M], outd[M];
string s[N], minn;
vector<pair<int, int> > g[M];
basic_string<int> tmp, ans;
bitset<N> vis;
bool flag;

void dfs(int u) {
    if (tmp.size() == n) {
        flag = true;
        for (auto v : tmp) ans += v;
        return;
    } for (auto [v, w] : g[u]) {
        if (flag) break;
        if (vis[w]) continue;
        tmp += w;
        vis[w] = true;
        dfs(v);
        tmp.pop_back();
        vis[w] = false;
    }
}

bool operator<(pair<int, int> a, pair<int, int> b) {
    return s[a.second] < s[b.second];
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cin >> n;
    for (int i = 1; i <= n; ++i) cin >> s[i];
    sort(s + 1, s + n + 1);  // new
    for (int i = 1; i <= n; ++i) {
        // if (i == 1) minn = s[i];  // old
        // else minn = min(minn, s[i]);  // old
        from = s[i].front() - 'a' + 1, to = s[i].back() - 'a' + 1;
        g[from].push_back({to, i});
        ++ind[to], ++outd[from];
    } from = to = 0;
    for (int i = 1; i <= LIM; ++i) {
        if (ind[i] - outd[i] == 1 && !to) to = i;
        else if (outd[i] - ind[i] == 1 && !from) from = i;
        else if (ind[i] != outd[i]) {
            cout << "***\n";
            return 0;
        }
    } minn = s[1]; // new
    if (!from) from = minn.front() - 'a' + 1;
    // for (int i = 1; i <= LIM; ++i) sort(g[i].begin(), g[i].end());  // old
    dfs(from);
    if (ans.size() != n) cout << "***\n";
    else for (int i = 0; i < ans.size(); ++i)
        cout << s[ans[i]] << ".\n"[i == ans.size() - 1];
    return 0;
}
2025/7/27 14:37
加载中...