POJ 2762 Going from u to v …(强连通分量+拓扑排序)
http://poj.org/problem?id=2762
题意:给你一个有向图,如果对于图中的任意一对点u和v都有一条从u到v的路或从v到u的路,那么就输出’Yes’,否则输出’No’.
分析:
首先求出该图的所有强连通分量,对于分量中的任意两点肯定都是有路的.我们只需要判断不同分量内的点是否有路即可.
把所有分量缩点,构成一个新的DAG图.现在的问题变成了:该DAG图是否对于任意两点都存在一条路.(想想为什么这个问题与原问题等价)
什么时候DAG图满足上述条件呢?多画几个图可以知道该DAG图只能是一条链的时候才行(自己画图验证一下,注意DAG图无环),即该DAG图拓扑排序时产生的是全序排列.(队列中始终只有一个元素)
AC代码:
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=1000+10;
int n,m;
vector<int> G[maxn],G2[maxn];
stack<int> S;
int dfs_clock, scc_cnt;
int pre[maxn],low[maxn],sccno[maxn];
int in[maxn];//新图的入度
void dfs(int u)
{
pre[u]=low[u]=++dfs_clock;
S.push(u);
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(!pre[v])
{
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(!sccno[v])
low[u]=min(low[u],pre[v]);
}
if(low[u]==pre[u])
{
scc_cnt++;
while(true)
{
int x=S.top(); S.pop();
sccno[x]=scc_cnt;
if(x==u) break;
}
}
}
void find_scc(int n)
{
scc_cnt=dfs_clock=0;
memset(pre,0,sizeof(pre));
memset(sccno,0,sizeof(sccno));
for(int i=1;i<=n;i++)
if(!pre[i]) dfs(i);
}
bool topo()
{
stack<int> Q;
int sum=0;//记录出Q的节点总数
for(int i=1;i<=scc_cnt;i++)
if(in[i]==0) Q.push(i);
while(!Q.empty())
{
if(Q.size()>1) return false;
int u=Q.top(); Q.pop();
sum++;
for(int i=0;i<G2[u].size();i++)
{
int v=G2[u][i];
if(--in[v]==0) Q.push(v);
}
}
return sum==scc_cnt;
}
int main()
{
int T; scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) G[i].clear();
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
}
find_scc(n);
//下面是对新图拓扑排序
bool map[maxn][maxn];
memset(map,0,sizeof(map));
for(int i=1;i<=scc_cnt;i++) G2[i].clear();
memset(in,0,sizeof(in));
for(int u=1;u<=n;u++)
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
int x=sccno[u],y=sccno[v];
if(!map[x][y] && x!=y)
{
G2[x].push_back(y);
map[x][y]=true;
in[y]++;
}
}
printf("%s\n",topo()?"Yes":"No");
}
return 0;
}
分享到:
相关推荐
POJ2186-Popular Cows ...【Tarjan+极大强连通分量+缩点】 解题报告+AC代码 http://hi.csdn.net/!s/BGDH68 附:我所有的POJ解题报告链接 . http://blog.csdn.net/lyy289065406/article/details/6642573
NULL 博文链接:https://200830740306.iteye.com/blog/603488
北大POJ1691-Painting A Board 【拓扑+DFS】 解题报告+AC代码
北大POJ2195-Going Home【费用流】 解题报告+AC代码 http://blog.csdn.net/lyy289065406/article/details/6732762
北大POJ3733-Changing Digits【DFS+强剪枝】 解题报告+AC代码
北大POJ3373-Changing Digits【DFS+强剪枝】 解题报告+AC代码
北大POJ3239-Solution to the n Queens Puzzle 解题报告+AC代码
POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类
北大POJ3009-Curling 2.0【DFS+Vector+回溯+剪枝】 解题报告+AC代码
poj 1091 拓扑排序加上foyld_warshall算法实现
poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题...
北大POJ3026-Borg Maze【BFS+Prim】 解题报告+AC代码
北大POJ初级-所有题目AC代码+解题报告
POJ3177-Redundant Paths 【Tarjan-边双连通分量-缩点】 解题报告+AC代码+测试数据 http://hi.csdn.net/!s/GPAY6Z 附:我所有的POJ解题报告链接 . http://blog.csdn.net/lyy289065406/article/details/6642573
北大POJ1159-Palindrome 解题报告+AC代码
此为本人在poj做过的经典题目的代码与一些经典数据结构算法的模板程序,如线段树,拓扑排序等
北大POJ2002-Squares 解题报告+AC代码
POJ1048,加强版的约瑟夫问题 难度中等
poj分类poj分类poj分类poj分类
POJ第1861题源码 POJ第1861题源码 POJ第1861题源码