uva 610 - Street Directions(双联通)
2015-09-12 22:17
375 查看
题目链接:uva 610 - Street Directions
求出所有边双联通分量,然后每一块单独考虑即可。
求出所有边双联通分量,然后每一块单独考虑即可。
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; typedef pair<int,int> pii; const int maxn = 1005; const int maxm = 1e6; int N, M, E, first[maxn], jump[maxm], link[maxm], vis[maxm]; int cntlock, pre[maxn], low[maxn], iscut[maxm]; void dfs (int u, int fa) { pre[u] = low[u] = ++cntlock; for (int i = first[u]; i != -1; i = jump[i]) { int v = link[i]; if (!pre[v]) { dfs(v, u); low[u] = min(low[u], low[v]); if (low[v] > pre[u]) iscut[i] = 1; } else if (pre[v] < pre[u] && v != fa) low[u] = min(low[u], pre[v]); } } void findEdge () { cntlock = 0; memset(pre, 0, sizeof(pre)); memset(iscut, 0, sizeof(iscut)); for (int i = 1; i <= N; i++) if (!pre[i]) dfs(i, -1); } inline void addEdge (int u, int v) { jump[E] = first[u]; link[E] = v; first[u] = E++; } void init () { E = 0; memset(first, -1, sizeof(first)); int u, v; while (M--) { scanf("%d%d", &u, &v); addEdge(u, v); addEdge(v, u); } findEdge(); } void put (int u) { if (pre[u]) return; pre[u] = ++cntlock; for (int i = first[u]; i != -1; i = jump[i]) { int v = link[i]; if (iscut[i]) { printf("%d %d\n", u, v); continue; } if (vis[i]) continue; vis[i] = vis[i^1] = 1; printf("%d %d\n", u, v); put(v); } } void solve () { cntlock = 0; memset(pre, 0, sizeof(pre)); memset(vis, 0, sizeof(vis)); for (int i = 1; i <= N; i++) put(i); } int main () { int cas = 1; while (scanf("%d%d", &N, &M) == 2 && N + M) { init(); printf("%d\n\n", cas++); solve(); printf("#\n"); } return 0; }
相关文章推荐
- Android屏幕适配
- hdu 5435 A serious math problem(数位dp)
- 光纤接口,光纤以太网口,以太网口三者区别
- Zabbix 自动注册
- opengl 3.3做底层 QML做UI渲染
- 攻击树分析
- HDU 1243 【基础DP 】
- Win7/8.1免费升级Win10-三种秘钥
- Unity 3D 泰课网打砖块实例 可以用来发射炮弹
- ZOJ 3826 Hierarchical Notation(模拟-字符串处理)
- C语言union(联合体 共用体)
- hdu 5435 Peace small elephant(矩阵快速幂)
- java修改文件名
- [ROR]部分特点记录
- Linux文件系统结构
- eclipse使用设置
- 做点mongo的笔记
- Java中集合类的内容总结
- 百度编程 兼职题目。
- HDU 5433