POJ 2762 强连通分量中存在单相连通边 【tarjan+toposort+缩点】.cpp
2012-10-03 21:33
344 查看
[b]题意:[/b]
[b] 给出一些房间之间的关系[/b]
问任意两个房间是否存在一条互通的路径..即单相连通..
输入:
给出T表示有T组数据
每组数据给出n m 表示n个房间 m个关系
接下来m行..每行给出a b 表示a房间 和 b房间之间是连通的..
如果任意两个房间之间存在单相连通..则输出yes 否则 no
[b]思路:[/b]
[b] 先用tarjan算法求出每个强连通分量..然后对每一个进行染色..[/b]
然后建图..拓扑排序..
如果排序不唯一..就是有超过两个点是有0个初度的..
这代表其中有两个房间是不相连的..
[b]Tips:[/b]
[b] 点太多或者边太多的情况下..[/b]
就要用前向星建图了..
[b]Code:[/b]
View Code
[b]题目链接:http://poj.org/problem?id=2762[/b]
[b] 给出一些房间之间的关系[/b]
问任意两个房间是否存在一条互通的路径..即单相连通..
输入:
给出T表示有T组数据
每组数据给出n m 表示n个房间 m个关系
接下来m行..每行给出a b 表示a房间 和 b房间之间是连通的..
如果任意两个房间之间存在单相连通..则输出yes 否则 no
[b]思路:[/b]
[b] 先用tarjan算法求出每个强连通分量..然后对每一个进行染色..[/b]
然后建图..拓扑排序..
如果排序不唯一..就是有超过两个点是有0个初度的..
这代表其中有两个房间是不相连的..
[b]Tips:[/b]
[b] 点太多或者边太多的情况下..[/b]
就要用前向星建图了..
[b]Code:[/b]
View Code
#include <stdio.h> #include <cstring> #include <algorithm> using namespace std; #define clr(x) memset(x, 0, sizeof(x)) const int INF = 0x1f1f1f1f; const int MAXN = 1010; int n, m; struct Edge { int to; int next; }edge[1000010], edge2[1000010]; int head[MAXN], head2[MAXN]; int tot, tot2; void add(int s, int u) { edge[tot].to = u; edge[tot].next = head[s]; head[s] = tot++; } void add2(int s, int u) { edge2[tot2].to = u; edge2[tot2].next = head2[s]; head2[s] = tot2++; } int ti, top, cnt; int dfn[MAXN], low[MAXN], ins[MAXN]; int col[MAXN], sta[MAXN]; void tarjan(int u) { int i, k; dfn[u] = low[u] = ++ti; sta[++top] = u; ins[u] = 1; for(i = head[u]; i != -1; i = edge[i].next) { k = edge[i].to; if(dfn[k] == 0) { tarjan(k); low[u] = min(low[u], low[k]); } else if(ins[k]) { low[u] = min(low[u], dfn[k]); } } if(dfn[u] == low[u]) { ++cnt; do { k = sta[top--]; col[k] = cnt; ins[k] = 0; }while(k != u); } } void solve_ta() { ti = top = cnt = 0; clr(dfn), clr(ins); for(int i = 1; i <= n; ++i) if(!dfn[i]) tarjan(i); } int ind[MAXN]; int q[MAXN]; int v[MAXN]; int f1, f2, num; void make_G() { int i, j, k; tot2 = 0; memset(head2, 0xff, sizeof(head2)); solve_ta(); for(i = 1; i <= n; ++i) for(j = head[i]; j != -1; j = edge[j].next) { k = edge[j].to; if(col[i] != col[k]) { add2(col[i], col[k]); ind[col[k]]++; } } } void toposort() { int front = 0, rear = 0; int i, k; f1 = 1, f2 = 0; clr(ind); make_G(); for(i = 1; i <= cnt; i++) if(ind[i] == 0) q[rear++] = i; if(rear > 1) f1 = -1; num = 0; while(front < rear) { int x = q[front++]; int tt = 0; num++; for(i = head2[x]; i!=-1; i = edge2[i].next) { k = edge2[i].to; ind[k]--; if(ind[k] == 0) { q[rear++] = k; tt++; } } if(tt > 1) f2 = -1; } } int main() { int i, j, k; int T; int a, b; bool flag; while(scanf("%d", &T) != EOF) while(T--) { tot = 0; memset(head, 0xff, sizeof(head)); flag = true; scanf("%d %d", &n, &m); while(m--) { scanf("%d %d", &a, &b); add(a, b); } toposort(); if(f1 == -1 || f2 == -1 || num != cnt) flag = false; if(flag) puts("Yes"); else puts("No"); } return 0; }
[b]题目链接:http://poj.org/problem?id=2762[/b]
相关文章推荐
- poj 2762 Going from u to v or from v to u? 【判断图是否为弱连通】 【tarjan求SCC + 缩点 + 拓扑排序】
- POJ2762 Going from u to v or from v to u? 强连通 Tarjan缩点+拓扑排序topsort
- POJ 2762 强连通分量 Tarjan + 缩点
- POJ 3352--Road Construction【无向图增加最少的边成为边双连通图 && tarjan求ebc && 缩点构造缩点树】
- [POJ 3177]Redundant Paths[边双连通][Tarjan][缩点]
- POJ 2762 tarjan缩点+并查集+度数
- poj 3177 Redundant Paths 【无向图增加最少的边是图成为边—双连通】【tarjan求EBC + 缩点 统计度数为1的EBC】
- POJ 3352 Road Construction POJ 3177 Redundant Paths(边双连通图 Tarjan+缩点)
- POJ 1236 Network of Schools(强连通 Tarjan+缩点)
- [练习][poj2762]tarjan缩点 Going from u to v or from v to u?
- POJ 3114 Countries in War 强连通tarjan缩点后 跑最短路spfa
- POJ_2186 Popular Cows (Tarjan 强连通分量 缩点)
- 连通分量模板:tarjan: 求割点 && 桥 && 缩点 && 强连通分量 && 双连通分量 && LCA(最近公共祖先)
- poj 2762 tarjan缩点+拓扑序
- POJ 1236 Network Of Schools ( tarjan求强连通分量 + 缩点成DAG图 )
- poj 2762 Going from u to v or from v to u?(强连通、缩点、拓扑)
- poj 2186 Popular Cows(tarjan + 强连通分量 + 缩点)
- POJ 1236 Network of Schools (tarjan求强连通,缩点)
- POJ 1236 Network of Schools(强连通 Tarjan+缩点)
- POJ 2762 Going from u to v or from v to u?【强连通+toposort】