poj 2762 Going from u to v or from v to u?

来源:互联网 发布:h5穿上军装源码 编辑:程序博客网 时间:2024/05/17 09:21

求有向图的弱连通分量。将有向图的所有的有向边替换为无向边,所得到的图称为原图的基图。如果一个有向图的基图是连通图,则有向图是弱连通图。如果有向图中,对于任意节点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[N];vector <int> graph[N];int n, m;int in[N],map[N][N];int dfs_clock, point, vis[N], pre[N], belong[N], low[N];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;}



0 0