POJ 2762 Going from u to v or from v to u? 强连通分量+DAG最长路
2015-10-12 10:49
495 查看
题意:给你一个有向图,问你是否对于任意两个点都有一条u->v或者v->u的路。
思路:对于一个强联通分量,里面的点一定满足条件,我们可以把他们缩点,而对于不在同一联通分量的点,如果存在一条路径,使得这条路径能够遍历所有点,即符合题意。
思路:对于一个强联通分量,里面的点一定满足条件,我们可以把他们缩点,而对于不在同一联通分量的点,如果存在一条路径,使得这条路径能够遍历所有点,即符合题意。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #define REP( i, a, b ) for( int i = a; i < b; i++ ) #define CLR( a , x ) memset( a , x , sizeof a ) const int maxn = 1000 + 10; const int maxe = 20000 + 10; struct Edge{ int v , next; Edge (int v = 0, int next = 0) : v(v), next(next) {} }; struct SCC{ int Head[maxn], cntE; int dfn[maxn], low[maxn], dfs_clock; int scc[maxn], scc_cnt; int Stack[maxn], top; bool ins[maxn]; Edge edge[maxe]; void init(){ top = 0; cntE = 0; scc_cnt = 0; dfs_clock = 0; CLR(ins, 0); CLR(dfn, 0); CLR(Head, -1); } void add(int u, int v){ edge[cntE] = Edge( v, Head[u]); Head[u] = cntE++; } void Tarjan(int u){ dfn[u] = low[u] = ++dfs_clock; Stack[top++] = u; ins[u] = 1; for (int i = Head[u] ; ~i ; i = edge[i].next){ int v = edge[i].v; if (!dfn[v]){ Tarjan (v) ; low[u] = min(low[u], low[v]) ; } else if (ins[v]) low[u] = min (low[u], dfn[v]) ; } if (low[u] == dfn[u]){ ++scc_cnt; while ( 1 ){ int v = Stack[--top]; ins[v] = 0; scc[v] = scc_cnt; if (v == u) break; } } } void find_scc(int n){ REP(i, 0, n) if(!dfn[i]) Tarjan (i) ; } }scc; int n, m; int in[maxn]; int dp[maxn]; int H[maxn], cnte; Edge e[maxe]; void Init(){ memset(H, -1, sizeof(H)); cnte = 0; } void Add(int u, int v){ e[cnte] = Edge(v, H[u]); H[u] = cnte++; } int DP(int u){ int &ans = dp[u]; if(ans > 0) return ans; for(int i = H[u]; ~i; i = e[i].next) ans = max(ans, DP(e[i].v) + 1); return ans; } void solve(){ scanf("%d%d", &n, &m); scc.init(); memset(dp, 0, sizeof(dp)); memset(in, 0, sizeof(in)); for(int i = 0; i < m; i++){ int u, v; scanf("%d%d", &u, &v); scc.add(u-1, v-1); } scc.find_scc(n); Init(); for(int i = 0; i < n; i++) for(int j = scc.Head[i]; ~j; j = scc.edge[j].next){ int u = i, v = scc.edge[j].v; if(scc.scc[u] != scc.scc[v]){ Add(scc.scc[u], scc.scc[v]); in[scc.scc[v]]++; } } int i; for(i = 1; i <= scc.scc_cnt; i++){ if(in[i] == 0){ DP(i); break; } } if(dp[i] == scc.scc_cnt - 1) printf("Yes\n"); else printf("No\n"); } int main() { int T; scanf("%d", &T); while(T--) solve(); return 0; }
相关文章推荐
- mogodb 复制集加分片环境搭建
- 如何在Ubuntu中让mongo远程可连接
- Go Ahead, Throw That Practice Out
- 数据挖掘算法-Apriori Algorithm(关联规则)
- 《Google Go: A Primer》学习笔记
- HOTPOWER.【专注游戏界面外包】/接游戏界面外包/logo外包/icon
- Git合入AOSP的Patch
- Google Guava教程
- [Django入门知识浅介]Django的一些优缺点评析
- [Django入门知识浅介]Django是如何处理URL请求的
- google product
- The Importance of Algorithms
- 【PAT】1092. To Buy or Not to Buy (20)
- 身份认证和消息合法性验证方案分享
- Django使用-Django搭建简单博客
- 略看AMP-来自 Google 的移动页面优化方案
- ubuntu上golang1.5.1安装
- 重学Statistics, Cha2 Descriptive Statistics (Categorical and Quantitative Data)
- Django搭建简单网页的学习笔记之四(Form)
- HUD The Frog's Games(二分)