POJ - 2762 Going from u to v or from v to u?(拓扑排序+强连通分量)
来源:互联网 发布:utorrent mac 设置 编辑:程序博客网 时间:2024/05/11 23:12
题目大意:给出N个点,M条有向边,问是否任意两点u,v都满足u能到达v或者v能到达u
解题思路:强连通分量内的所有的点都满足,接着要判断一下其他的点能否满足了
求出所有的强连通分量,接着缩点,用桥连接,形成新的图(以下所说的点都是指新的图的点)
如果一个点同时指向另外两个不同的点,那么这两个点之间肯定是不能相互到达的,所以拓扑排序一下,就可以知道是否符合了
#include <cstdio>#include <cstring>#define min(a,b) ((a) < (b) ? (a) : (b))#define N 10100#define M 60100struct Edge{ int from, to, next;}E[M];struct Node{ int x, y;}node[M];int n, m, tot, dfs_clock, top, scc_cnt;int head[N], pre[N], stack[N], sccno[N], lowlink[N], in[N];void AddEdge(int u, int v) { E[tot].from = u; E[tot].to = v; E[tot].next = head[u]; head[u] = tot++;}void init() { scanf("%d%d", &n, &m); memset(head, -1, sizeof(head)); tot = 0; int u, v; for (int i = 0; i < m; i++) { scanf("%d%d", &node[i].x, &node[i].y); AddEdge(node[i].x, node[i].y); }}void dfs(int u) { pre[u] = lowlink[u] = ++dfs_clock; stack[++top] = u; int v; for (int i = head[u]; i != -1; i = E[i].next) { v = E[i].to; if (!pre[v]) { dfs(v); 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++; while (1) { v = stack[top--]; sccno[v] = scc_cnt; if (v == u) break; } }}int find() { int cnt = 0, num; for (int i = 1; i <= scc_cnt; i++) { if (in[i] == 0) { cnt++; num = i; } } if (cnt == 1) return num; return 0;}bool TopoOrder(){ int cnt = 0; int u; while (u = find()) { in[u] = -1; for (int i = head[u]; i != -1; i = E[i].next) { in[E[i].to]--; } cnt++; } return cnt == scc_cnt;}void solve() { memset(pre, 0, sizeof(pre)); memset(sccno, 0, sizeof(sccno)); dfs_clock = top = scc_cnt = 0; for (int i = 1; i <= n; i++) if (!pre[i]) dfs(i); if (scc_cnt == 1) { printf("Yes\n"); return ; } memset(in, 0, sizeof(in)); memset(head, -1, sizeof(head)); tot = 0; int u, v; for (int i = 0; i < m; i++) { u = sccno[node[i].x]; v = sccno[node[i].y]; if (u != v) { in[v]++; AddEdge(u, v); } } int ans = 0; for (int i = 1; i <= scc_cnt; i++) if (in[i] == 0) ans++; if (ans > 1) { printf("No\n"); return ; } if (TopoOrder()) printf("Yes\n"); else printf("No\n");}int main() { int test; scanf("%d", &test); while (test--) { init(); solve(); } return 0;}
0 0
- POJ 2762 Going from u to v or from v to u? / 强连通分量&&拓扑
- [POJ 2762]Going from u to v or from v to u? (强连通分量+拓扑排序)
- POJ 2762 Going from u to v or from v to u?(强连通分量+拓扑排序)
- POJ - 2762 Going from u to v or from v to u?(拓扑排序+强连通分量)
- poj2762 Going from u to v or from v to u? 强连通分量 + 拓扑排序
- poj 2762 Going from u to v or from v to u?(强连通分量)
- POJ 2762 Going from u to v or from v to u?(强连通+拓扑)
- POJ 2762 — Going from u to v or from v to u? 强连通+拓扑
- POJ 2762 Going from u to v or from v to u?【强连通Kosaraju+拓扑排序】
- POJ 2762 Going from u to v or from v to u?(强联通,拓扑排序)
- POJ 2762 Going from u to v …(强连通分量+拓扑排序)
- POJ 2762 Going from u to v …(强连通分量+拓扑排序)
- POJ-2762 Going from u to v or from v to u? (强连通分量[Tarjan]&&(拓扑排序||树形DP))
- POJ2762 Going from u to v or from v to u?(强连通分量缩点+拓扑排序)
- poj2762 Going from u to v or from v to u? 有向图 强连通分量 拓扑排序
- poj2762 Going from u to v or from v to u?--trajan算法 & 强连通分量 & 缩点 & 拓扑排序
- POJ 2762 Going from u to v or from v to u?(强连通分量+缩点)
- POJ 2762 Going from u to v or from v to u? 强连通分量+DAG最长路
- SSH-Struts2简单的自定义拦截器MethodFilterInterceptor
- 高仿 QQ影音播放器 皮肤
- LINK:fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- 欢迎使用CSDN-markdown编辑器
- iGrimace1.44基本使用方式
- POJ - 2762 Going from u to v or from v to u?(拓扑排序+强连通分量)
- php 二进制文件上传
- iGrimace安装包下载地址
- JAVA List删除时需注意的地方
- iGrimace iOS应用闪退或图标消失的解决办法
- HDU 5386 Cover(模拟)
- MFC动态创建菜单
- 算法导论 10.4.5 O(1)空间遍历二叉树
- 利用HTTP-only Cookie缓解XSS