HDU - 3594 Cactus
这是一个有向仙人掌的题目,要求判定给定的图是不是强连通图,而且每一条边只能出现在一个环中,这里有一个介绍有向仙人掌的文档:https://files.cnblogs.com/ambition/cactus_solution.pdf。
有向仙人掌的判定:
1.dfs树中不存在横叉边;
2.dfs树中不存在lowlink[v]>pre[u],也就是不存在桥,lowlink[v]表示从v及其子节点出发能回到的pre值最小的祖先的pre值;
3.从节点u出发的点v,满足pre[v] < pre[u](当(u,v)是反向边时),和lowlink[v] < pre[u]的个数< 2.
更详细的解答见这里:http://blog.csdn.net/frog1902/article/details/10051323#comments
我又按照这思路简单写了一遍,加深理解>.<
代码:

1 #include <iostream> 2 #include <sstream> 3 #include <cstdio> 4 #include <climits> 5 #include <cstring> 6 #include <cstdlib> 7 #include <string> 8 #include <stack> 9 #include <map> 10 #include <cmath> 11 #include <vector> 12 #include <queue> 13 #include <algorithm> 14 #define esp 1e-6 15 #define pi acos(-1.0) 16 #define pb push_back 17 #define mp(a, b) make_pair((a), (b)) 18 #define in freopen("in.txt", "r", stdin); 19 #define out freopen("out.txt", "w", stdout); 20 #define print(a) printf("%d\n",(a)); 21 #define bug puts("********))))))"); 22 #define stop system("pause"); 23 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++) 24 #define inf 0x0f0f0f0f 25 26 using namespace std; 27 typedef long long LL; 28 typedef vector<int> VI; 29 typedef pair<int, int> pii; 30 typedef vector<pii,int> VII; 31 typedef vector<int>:: iterator IT; 32 33 const int maxn = 20000 + 10; 34 int pre[maxn], lowlink[maxn], cost[maxn], vis[maxn], dfs_clock; 35 VI g[maxn]; 36 int flag; 37 void dfs(int u) 38 { 39 lowlink[u] = pre[u] = ++dfs_clock; 40 vis[u] = 1; 41 for(int i = 0; i < g[u].size(); i++) 42 { 43 if(!flag) return; 44 int v = g[u][i]; 45 if(!vis[v] && pre[v]) 46 { 47 flag = 0; 48 return; 49 } 50 if(!pre[v]) 51 { 52 dfs(v); 53 lowlink[u] = min(lowlink[u], lowlink[v]); 54 if(lowlink[v] < pre[u]) cost[u]++; 55 if(lowlink[v] > pre[u]) 56 { 57 flag = 0; 58 return; 59 } 60 } 61 else if(pre[v] < pre[u]) 62 { 63 lowlink[u] = min(lowlink[u], pre[v]); 64 cost[u]++; 65 } 66 if(cost[u] > 1) 67 { 68 flag = 0; 69 return; 70 } 71 } 72 vis[u] = 0; 73 } 74 void solve(int n) 75 { 76 memset(pre, 0, sizeof(pre)); 77 memset(vis, 0, sizeof(vis)); 78 memset(lowlink, 0, sizeof(lowlink)); 79 memset(cost, 0, sizeof(cost)); 80 81 dfs_clock = 0; 82 for(int i = 0; i < n ; i++) 83 if(!pre[i]) 84 { 85 dfs(i); 86 if(!flag) break; 87 } 88 } 89 int main(void) 90 { 91 int T; 92 for(int t = scanf("%d", &T); t <= T; t++) 93 { 94 flag = 1; 95 for(int i = 0; i < maxn; i++) 96 g[i].clear(); 97 int n; 98 scanf("%d", &n); 99 int u, v; 100 while(scanf("%d%d", &u, &v), u||v) 101 { 102 g[u].pb(v); 103 } 104 solve(n); 105 if(flag) 106 puts("YES"); 107 else puts("NO"); 108 } 109 return 0; 110 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· dotnet 9 通过 AppHostRelativeDotNet 指定自定义的运行时路径
· 如何统计不同电话号码的个数?—位图法
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 从零实现富文本编辑器#3-基于Delta的线性数据结构模型
· 记一次 .NET某旅行社酒店管理系统 卡死分析
· 用c#从头写一个AI agent,实现企业内部自然语言数据统计分析
· 三维装箱问题(3D Bin Packing Problem, 3D-BPP)
· Windows上,10分钟构建一个本地知识库
· 使用 AOT 编译保护 .NET 核心逻辑,同时支持第三方扩展
· Java虚拟机代码是如何一步一步变复杂且难以理解的?