hdu 4612 Warm up(缩点+树直径)
2015-10-26 21:37
120 查看
题目链接:hdu 4612 Warm up
解题思路
先双联通缩点,然后对缩完点的树求树的直径。代码
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int maxn = 200005; const int maxm = 1000005; int N, M, E, first[maxn], jump[maxm<<1], linker[maxm<<1]; int dfsclock, L[maxm], R[maxm], iscut[maxm], pre[maxn]; int dfs (int u, int fa) { int lowu = pre[u] = ++dfsclock; for (int i = first[u]; i + 1; i = jump[i]) { int v = linker[i]; if (!pre[v]) { int lowv = dfs(v, u); lowu = min(lowu, lowv); if (lowv > pre[u]) iscut[i>>1] = 1; } else if (pre[v] < pre[u] && v != fa) lowu = min(lowu, pre[v]); } return lowu; } void dfs (int u, int fa, int be) { pre[u] = be; for (int i = first[u]; i + 1; i = jump[i]) { int v = linker[i]; if (pre[v] || iscut[i>>1]) continue; dfs(v, u, be); } } void findEdge () { dfsclock = 0; memset(pre, 0, sizeof(pre)); memset(iscut, 0, sizeof(iscut)); for (int i = 1; i <= N; i++) if (!pre[i]) dfs(i, -1); dfsclock = 0; memset(pre, 0, sizeof(pre)); for (int i = 1; i <= N; i++) if (!pre[i]) dfs(i, -1, ++dfsclock); } void addEdge(int u, int v) { jump[E] = first[u]; linker[E] = v; first[u] = E++; } void init () { E = 0; memset(first, -1, sizeof(first)); for (int i = 0; i < M; i++) { scanf("%d%d", &L[i], &R[i]); addEdge(L[i], R[i]); addEdge(R[i], L[i]); } findEdge(); } const int inf = 0x3f3f3f3f; int D[maxn]; int solve () { int n = dfsclock, u; queue<int> que; que.push(1); memset(D, inf, sizeof(D)); D[1] = 0; while (!que.empty()) { u = que.front(); que.pop(); for (int i = first[u]; i + 1; i = jump[i]) { int v = linker[i]; if (D[v] > D[u] + 1) { D[v] = D[u] + 1; que.push(v); } } } que.push(u); memset(D, inf, sizeof(D)); D[u] = 0; while (!que.empty()) { u = que.front(); que.pop(); for (int i = first[u]; i + 1; i = jump[i]) { int v = linker[i]; if (D[v] > D[u] + 1) { D[v] = D[u] + 1; que.push(v); } } } return n - D[u] - 1; } int main () { while (scanf("%d%d", &N, &M) == 2 && N + M) { init(); E = 0; memset(first, -1, sizeof(first)); for (int i = 0; i < M; i++) if (iscut[i]) { addEdge(pre[L[i]], pre[R[i]]); addEdge(pre[R[i]], pre[L[i]]); } printf("%d\n", solve()); } return 0; }
相关文章推荐
- Java编译器——javac.exe
- Java对象类型转换的四个经验
- Python函数_返回值
- R绘图
- Django实现一个相片管理系统01
- hdoj1576A/B【扩展欧几里得】
- 快速索引 (对View的自定义,黑马程序员)
- iOS launchScreen页面如何加载动画
- 单片机TM4C123学习(二):中断与按键控制
- Android上面通过URL来启动本地应用
- C# combox加入时间段 yyyy/mm/dd-yyyy/mm/dd
- 拓扑排序实现(伪代码)
- Search in Rotated Sorted Array
- iOS中相对1970的时间转换为现在时间
- mac提升yosemite后php 扩展修复
- C++:运算符重载函数之友元运算符重载
- xml文件存储
- 软件工程第二次作业(2)
- Boa服务器的移植
- CSS常用选择器及优先级