LightOJ - 1417 Forwarding Emails(强连通+dfs)
2015-11-10 00:12
495 查看
题目大意:你有一个秘密,但你只能告诉一个。这个人如果有认识的人的话,他就会把你的秘密告诉出去,这样就一传十,十传百了。现在你想要知道,最多能有多少人知道
解题思路:同一个连通分量内的人都是可知的,所以缩点,然后连边,从入度为0的点出发,dfs找出所能到的最远处,在dfs过程中统计一下有多少个人知道
解题思路:同一个连通分量内的人都是可知的,所以缩点,然后连边,从入度为0的点出发,dfs找出所能到的最远处,在dfs过程中统计一下有多少个人知道
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <map> using namespace std; const int N = 50010; struct Edge{ int u, v, next; Edge() {} Edge(int u, int v, int next): u(u), v(v), next(next) {} }E ; int head , pre , lowlink , sccno , num , Stack , in ; int dfs_clock, scc_cnt, top, n, m, cas = 1; bool vis ; vector<int> V ; void init() { scanf("%d", &n); memset(head, -1, sizeof(head)); int u, v; for (int i = 0; i < n; i++) { scanf("%d%d", &u, &v); E[i] = Edge(u, v, head[u]); head[u] = i; } } void dfs(int u, int fa) { pre[u] = lowlink[u] = ++dfs_clock; Stack[++top] = u; for (int i = head[u]; ~i; i = E[i].next) { int v = E[i].v; if (!pre[v]) { dfs(v, u); lowlink[u] = min(lowlink[u], lowlink[v]); } else if (!sccno[v]) lowlink[u] = min(lowlink[u], pre[v]); } if (pre[u] == lowlink[u]) { scc_cnt++; int x = 0; num[scc_cnt] = 0; while (1) { x = Stack[top--]; sccno[x] = scc_cnt; num[scc_cnt]++; if (x == u) break; } } } int dfs2(int u){ int Max = 0; for (int i = 0; i < V[u].size(); i++) { int v = V[u][i]; Max = max(Max, dfs2(v)); } return Max + num[u]; } void solve() { memset(pre, 0, sizeof(pre)); memset(sccno, 0, sizeof(sccno)); dfs_clock = scc_cnt = 0; for (int i = 1; i <= n; i++) if (!pre[i]) dfs(i, -1); if (scc_cnt == 1) { printf("Case %d: %d\n", cas++, 1); return ; } memset(in, 0, sizeof(in)); for (int i = 1; i <= scc_cnt; i++) V[i].clear(); for (int i = 0; i < n; i++) { int u = sccno[E[i].u]; int v = sccno[E[i].v]; if (u == v) continue; in[v]++; V[u].push_back(v); } int Max = 0, pos; for (int i = 1; i <= scc_cnt; i++) if (!in[i]) { int t = dfs2(i); if (t > Max) { Max = t; pos = i; } } for (int i = 1; i <= n; i++) if (sccno[i] == pos) { printf("Case %d: %d\n", cas++, i); return ; } } int main() { int test; scanf("%d", &test); while (test--) { init(); solve(); } return 0; }
相关文章推荐
- 如何写好 C main 函数
- LightOJ - 1086 Jogging Trails(欧拉+状态压缩)
- 【Alpha】Daily Scrum Meeting第七次
- 【Alpha】Daily Scrum Meeting第七次
- TinyOS06:Avrora的Mailing List
- poj 2010 Moo University - Financial Aid 优先队列
- fibonacci && climbing-stairs
- LightOJ 1021 - Painful Bases(dp)
- http://blog.csdn.net/jadyer/article/details/6013743
- hdu 3264 Open-air shopping malls(几何)
- hdu4770 Lights Against Dudely
- Gradle project sync failed. Please fix your project and try again.
- 正确使用Block避免Cycle Retain和Crash
- Scala初学者学习资料:main(String[])
- 运行Scala应用 Main方法
- .NET 4.0 使用 asyn await
- 父进程等待子进程结束 waitpid wait
- Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON
- git常见错误failed to push some refs to
- NovaException: Unexpected vif_type=binding_failed