1 条题解
-
0
冷知识,这个国王是色批
虽然只有一种味道,但真的很 鲜~
葵花籽味
#include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <stack> using namespace std; const int MAXN = 4005; // 王子和姑娘总共最多 4000 个点 vector<int> graph[MAXN]; // 残量网络的邻接表 vector<int> likes[MAXN]; // 原始喜好关系 int match_girl[MAXN]; // match_girl[i] = 姑娘 i 匹配的王子 int match_prince[MAXN]; // match_prince[i] = 王子 i 匹配的姑娘 // Tarjan 算法相关变量 int dfn[MAXN], low[MAXN], belong[MAXN]; bool instack[MAXN]; stack<int> st; int index_num, scc_count; void tarjan(int u) { dfn[u] = low[u] = ++index_num; st.push(u); instack[u] = true; for (int v : graph[u]) { if (!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if (instack[v]) { low[u] = min(low[u], dfn[v]); } } if (dfn[u] == low[u]) { scc_count++; int v; do { v = st.top(); st.pop(); instack[v] = false; belong[v] = scc_count; } while (v != u); } } int main() { // 优化输入输出 ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; // 1. 读取喜好关系 for (int i = 1; i <= n; i++) { int k; cin >> k; likes[i].resize(k); for (int j = 0; j < k; j++) { cin >> likes[i][j]; } } // 2. 读取初始匹配 memset(match_girl, -1, sizeof(match_girl)); memset(match_prince, -1, sizeof(match_prince)); for (int i = 1; i <= n; i++) { cin >> match_prince[i]; match_girl[match_prince[i]] = i; } // 3. 构建残量网络 // 点 1~n 表示王子,点 n+1~2n 表示姑娘 // 如果 (u, v) 在匹配中,加边 v+n -> u // 如果 (u, v) 不在匹配中,加边 u -> v+n for (int u = 1; u <= n; u++) { for (int v : likes[u]) { if (match_prince[u] == v) { // 匹配边:姑娘 -> 王子 graph[v + n].push_back(u); } else { // 非匹配边:王子 -> 姑娘 graph[u].push_back(v + n); } } } // 4. 求强连通分量 memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(instack, false, sizeof(instack)); index_num = 0; scc_count = 0; for (int i = 1; i <= 2 * n; i++) { if (!dfn[i]) { tarjan(i); } } // 5. 判定可行边并输出 for (int u = 1; u <= n; u++) { vector<int> valid_girls; for (int v : likes[u]) { // 判定条件: // 1. (u, v) 是匹配边 // 2. 或者 u 和 v+n 在同一个强连通分量中 if (match_prince[u] == v || belong[u] == belong[v + n]) { valid_girls.push_back(v); } } // 输出 cout << valid_girls.size(); sort(valid_girls.begin(), valid_girls.end()); for (int girl : valid_girls) { cout << " " << girl; } cout << "\n"; } return 0; }仅供参考,以实际葵花籽为准
信息
- ID
- 321
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者