首页 > 代码库 > HDU 3639 Hawk-and-Chicken(强连通)
HDU 3639 Hawk-and-Chicken(强连通)
HDU 3639 Hawk-and-Chicken
题目链接
题意:就是在一个有向图上,满足传递关系,比如a->b, b->c,那么c可以得到2的支持,问得到支持最大的是谁,并且输出这些人
思路:先强连通的缩点,然后逆向建图,对于每个出度为0的点,进行dfs求哪些点可达这个点
代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <stack> #include <map> #include <queue> using namespace std; const int N = 5005; int t, n, m; int sccn, dfs_clock, sccno[N], pre[N], dfn[N]; stack<int> S; vector<int> g[N], save[N], scc[N]; void dfs_scc(int u) { pre[u] = dfn[u] = ++dfs_clock; S.push(u); for (int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if (!pre[v]) { dfs_scc(v); dfn[u] = min(dfn[u], dfn[v]); } else if (!sccno[v]) dfn[u] = min(dfn[u], pre[v]); } if (pre[u] == dfn[u]) { ++sccn; save[sccn].clear(); while (1) { int x = S.top(); S.pop(); sccno[x] = sccn; save[sccn].push_back(x); if (x == u) break; } } } void find_scc() { dfs_clock = sccn = 0; memset(pre, 0, sizeof(pre)); memset(sccno, 0, sizeof(sccno)); for (int i = 0; i < n; i++) if (!pre[i]) dfs_scc(i); } int out[N]; int ans[N], an, dp[N], vis[N]; int dfs(int u) { vis[u] = 1; int ans = save[u].size(); for (int i = 0; i < scc[u].size(); i++) { int v = scc[u][i]; if (vis[v]) continue; ans += dfs(v); } return ans; } int main() { int cas = 0; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) g[i].clear(); int u, v; while (m--) { scanf("%d%d", &u, &v); g[u].push_back(v); } find_scc(); memset(out, 0, sizeof(out)); for (int i = 1; i <= sccn; i++) scc[i].clear(); for (int u = 0; u < n; u++) { for (int j = 0; j < g[u].size(); j++) { int v = g[u][j]; if (sccno[u] != sccno[v]) { scc[sccno[v]].push_back(sccno[u]); out[sccno[u]]++; } } } int Max = 0; for (int i = 1; i <= sccn; i++) if (!out[i]) { memset(vis, 0, sizeof(vis)); dp[i] = dfs(i); Max = max(Max, dp[i]); } an = 0; for (int i = 1; i <= sccn; i++) { if (!out[i] && dp[i] == Max) { for (int j = 0; j < save[i].size(); j++) { ans[an++] = save[i][j]; } } } sort(ans, ans + an); printf("Case %d: %d\n", ++cas, Max - 1); for (int i = 0; i < an; i++) printf("%d%c", ans[i], i == an - 1 ? '\n' : ' '); } return 0; }
HDU 3639 Hawk-and-Chicken(强连通)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。