poj 2762 Going from u to v or from v to u?
2015-03-16 22:32
281 查看
求有向图的弱连通分量。将有向图的所有的有向边替换为无向边,所得到的图称为原图的基图。如果一个有向图的基图是连通图,则有向图是弱连通图。如果有向图中,对于任意节点v1和v2,至少存在从v1到v2和从v2到v1的路径中的一条,则原图为单向连通图。即设G=<V,E>是有向图,如果u->v意味着图G至多包含一条从u到v的简单路径,则图G为单连通图。强连通图、连通图、单向连通图三者之间的关系是,强连通图必然是单向连通的,单向连通图必然是弱连通图。
做法就是:先强连通缩点,形成一棵树或者森林,如果存在一个连接各个点的单链,那么满足弱连通的条件,单链就是指不能有分叉,使用拓扑排序解决这个问题。
代码:
做法就是:先强连通缩点,形成一棵树或者森林,如果存在一个连接各个点的单链,那么满足弱连通的条件,单链就是指不能有分叉,使用拓扑排序解决这个问题。
代码:
#include <stack> #include <queue> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 1010; const int M = 6010; queue <int> Q; stack <int> S; vector <int> vt ; vector <int> graph ; int n, m; int in ,map ; int dfs_clock, point, vis , pre , belong , low ; void init(){ while(!S.empty()) S.pop(); while(!Q.empty()) Q.pop(); for(int i=1; i<=n; i++){ vt[i].clear(); graph[i].clear(); vis[i] = 0; pre[i] = 0; in[i] = 0; } memset(map, 0, sizeof(map)); dfs_clock = point = 0; } void Tarjan(int u){//强连通缩点 pre[u] = low[u] = ++dfs_clock; vis[u] = 1; S.push(u); for(int i=0; i<vt[u].size(); i++){ int v = vt[u][i]; if(!pre[v]){ Tarjan(v); low[u] = min(low[u], low[v]); } else if(vis[v] && pre[v] < low[u]) low[u] = pre[v]; } if(pre[u] == low[u]){ point++; int x; do{ x = S.top(); vis[x] = 0; belong[x] = point; S.pop(); }while(u != x); } return; } bool topo_sort(){//拓扑排序 int sum = 0; for(int i=1; i<=point; i++) if(!in[i]){ sum++; if(sum > 1) return false; Q.push(i); } while(!Q.empty()){ int u = Q.front(); Q.pop(); int sum = 0; for(int i=0; i<graph[u].size(); i++){ int v = graph[u][i]; in[v]--; if(!in[v]){ sum++; Q.push(v); } } if(sum > 1) return false; } return true; } int main(){ int cas; scanf("%d",&cas); while(cas--){ scanf("%d%d", &n, &m); /*if(n < 2){//刚开始就WA在这里 puts("No"); continue; }*/ init(); for(int i=0; i<m; i++){ int u, v; scanf("%d%d",&u, &v); vt[u].push_back(v); } for(int i=1; i<=n; i++) if(!pre[i]) Tarjan(i); for(int i=1; i<=n; i++){ for(int j=0; j<vt[i].size(); j++){ int v = vt[i][j]; int a = belong[i], b = belong[v]; if(!map[a][b] && a != b){//重新建图,去掉重编 map[a][b] = 1; graph[a].push_back(b); in[b]++; } } } if(topo_sort()) puts("Yes"); else puts("No"); } return 0; }
相关文章推荐
- poj 2762 Going from u to v or from v to u?
- POJ 2762 Going from u to v or ... 弱连通图 tarjan
- 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?(Tarjan + 拓扑排序)
- 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 ... 弱连通图 tarjan
- poj 2762 Going from u to v or from v to u 判断图中任意两点x,y是否总是存在x->y或者y->x
- 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最长路
- 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 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?(有向图单向连通)