题解
2025-10-08 13:21:19
发布于:浙江
0阅读
0回复
0点赞
解题
#include<bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int N, M;
cin >> N >> M;
// 存储每个观察结果对应的边
vector<vector<pair<int, int>>> edges_by_obs;
for (int i = 0; i < M; ++i) {
int m;
cin >> m;
vector<int> cows(m);
for (int j = 0; j < m; ++j) {
cin >> cows[j];
}
// 生成连续对的边
vector<pair<int, int>> edges;
for (int j = 0; j < m - 1; ++j) {
edges.emplace_back(cows[j], cows[j + 1]);
}
edges_by_obs.push_back(edges);
}
// 二分查找最大的X
int low = 0, high = M, best_X = 0;
while (low <= high) {
int mid = (low + high) / 2;
// 构建图
vector<vector<int>> adj(N + 1);
vector<int> in_degree(N + 1, 0);
for (int i = 0; i < mid; ++i) {
for (auto& e : edges_by_obs[i]) {
int u = e.first, v = e.second;
adj[u].push_back(v);
in_degree[v]++;
}
}
// Kahn's算法检查是否为DAG
queue<int> q;
vector<int> temp_in = in_degree;
for (int i = 1; i <= N; ++i) {
if (temp_in[i] == 0) {
q.push(i);
}
}
int cnt = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
cnt++;
for (int v : adj[u]) {
temp_in[v]--;
if (temp_in[v] == 0) {
q.push(v);
}
}
}
if (cnt == N) {
best_X = mid;
low = mid + 1;
} else {
high = mid - 1;
}
}
// 生成最佳X对应的字典序最小拓扑排序
vector<vector<int>> adj_final(N + 1);
vector<int> in_degree_final(N + 1, 0);
for (int i = 0; i < best_X; ++i) {
for (auto& e : edges_by_obs[i]) {
int u = e.first, v = e.second;
adj_final[u].push_back(v);
in_degree_final[v]++;
}
}
// 使用最小堆确保字典序最小
priority_queue<int, vector<int>, greater<int>> pq;
for (int i = 1; i <= N; ++i) {
if (in_degree_final[i] == 0) {
pq.push(i);
}
}
vector<int> result;
while (!pq.empty()) {
int u = pq.top();
pq.pop();
result.push_back(u);
for (int v : adj_final[u]) {
in_degree_final[v]--;
if (in_degree_final[v] == 0) {
pq.push(v);
}
}
}
// 输出结果
for (int i = 0; i < N; ++i) {
if (i > 0) cout << " ";
cout << result[i];
}
cout << endl;
return 0;
}
看到这了,给个赞呗
这里空空如也






有帮助,赞一个