题意:现有一张圆桌,有若干喜欢关系,每个人只在喜欢的人身旁就坐,问该圆桌最多能坐多少人;
共有n个人,每个人都只喜欢一个人(不能是自己)
传送门
题解:由于喜欢是单向的,所以可以通过构造有向图,根据有向图判断最大环即可,但有个问题,当两个人互相喜欢时,则两人的两侧可连接指向他们的最长边,因此需要特判互相喜欢的情况。
int maximumInvitations(vector<int>& favorite) {
int n = favorite.size();
vector<int> indeg(n), vis(n), dp(n, 1);
for (auto &x : favorite) ++indeg[x];
queue<int> q;
for (int i = 0; i < n; ++i)
if (!indeg[i])
q.push(i);
while (!q.empty()) {
int u = q.front();
vis[u] = true;
q.pop();
int v = favorite[u];
dp[v] = max(dp[v], dp[u]+1);
--indeg[v];
if (!indeg[v])
q.push(v);
}
int ring = 0, total = 0;
for (int i = 0; i < n; ++i) {
if (!vis[i]) {
int j = favorite[i];
// 互相喜欢,累加答案
if (favorite[j] == i) {
total += dp[i] + dp[j];
vis[i] = vis[j] = true;
}
else {
// 找最大环
int u = i, cnt = 0;
while (1) {
++cnt;
u = favorite[u];
vis[u] = true;
if (u == i)
break;
}
ring = max(ring, cnt);
}
}
}
// 答案只能是 【互相喜欢+最长边】 或 【最大环】 二者之一
return max(ring, total);
}