HDU - 3594 Cactus(仙人掌图)
2015-08-12 00:50
357 查看
题目大意:给出仙人掌图的定义:
1.必须是强连通
2.每条边只能属于一个环
解题思路:在tarjan算法中加入点东西就可以判断了
只要该点能连到之前的点,那么形成环了,找到这个环的所有的边,并标记
如果有一条边被标记了两次了,那图就不是仙人掌图了
关键是怎么找到这个环的所有边,我们可以引入另一个栈,这个栈存放的是边的序号
假设当前点为u,u点连回之前的点是v,那么就从栈里面找边,找到出发点为v的边为止,找到的这些边都是环上的边,这个和tarjan算法的找同一个连通分量的点的道理是一样
1.必须是强连通
2.每条边只能属于一个环
解题思路:在tarjan算法中加入点东西就可以判断了
只要该点能连到之前的点,那么形成环了,找到这个环的所有的边,并标记
如果有一条边被标记了两次了,那图就不是仙人掌图了
关键是怎么找到这个环的所有边,我们可以引入另一个栈,这个栈存放的是边的序号
假设当前点为u,u点连回之前的点是v,那么就从栈里面找边,找到出发点为v的边为止,找到的这些边都是环上的边,这个和tarjan算法的找同一个连通分量的点的道理是一样
[code]#include <cstdio> #include <cstring> #pragma comment(linker, "/STACK:102400000,102400000") #define N 20010 #define M 50010 #define min(a,b) ((a) < (b) ? (a) : (b)) struct Edge{ int from, to, next, id; }E[M]; int head , pre , lowlink , sccno , stack , stack2[M]; int tot, n, scc_cnt, dfs_clock, top, top2; int queue[M]; bool vis[M]; bool flag; void AddEdge(int from, int to) { E[tot].from = from; E[tot].to = to; E[tot].next = head[from]; E[tot].id = tot; head[from] = tot++; } void init(){ scanf("%d", &n); memset(head, -1, sizeof(head)); tot = 0; int u, v; while (scanf("%d%d", &u, &v) && u + v) { AddEdge(u, v); } } void dfs(int u) { pre[u] = lowlink[u] = ++dfs_clock; stack[++top] = u; for (int i = head[u]; i != -1; i = E[i].next) { int v = E[i].to; stack2[++top2] = E[i].id; if (!pre[v]) { dfs(v); lowlink[u] = min(lowlink[u], lowlink[v]); } else if(!sccno[v]) { lowlink[u] = min(lowlink[u], pre[v]); int tmp = top2; while (1){ int id = stack2[top2--]; if (vis[id]) flag = true; vis[id] = true; if (E[id].from == v) break; } top2 = tmp; } top2--; } int x; if (pre[u] == lowlink[u]) { scc_cnt++; while (1) { x = stack[top--]; sccno[x] = scc_cnt; if (x == u) break; } } } void solve() { memset(pre, 0, sizeof(pre)); memset(sccno, 0, sizeof(sccno)); memset(vis, 0, sizeof(vis)); dfs_clock = top = top2 = scc_cnt = 0; flag = false; dfs(0); for (int i = 0; i < n; i++) { if (sccno[i] != 1) { printf("NO\n"); return ; } } if (flag) printf("NO\n"); else printf("YES\n"); } int main() { int test; scanf("%d", &test); while (test--) { init(); solve(); } return 0; }
相关文章推荐
- Dijkstra算法总结
- GP规范学习(一)
- CoreData的基本使用
- ZOJ 3721 Final Exam Arrangement(贪心)
- 编译cocos2dx 工程,ndk-build 报错:
- MyEclipse6.6 汉化过程
- 在Android上面如何使用带有心跳检测的Socket
- 搭建java开发环境
- POJ 1741 Tree(树分治|ltc男人八题)
- canvas阴影
- Codeforces 245G Suggested Friends 暴力乱搞
- 对sql的查询语句做成对象式,简单实现。Where部分
- php-实例1:简单的文章管理系统
- hadoop之家族
- 博弈题集
- java封装AES加密算法
- HDU - 1827 Summer Holiday(强连通分量+贪心)
- vsftpd 安装与使用
- iOS- JSon和Xml解析,与服务器交互数据的解析详解与使用,各种解析方式详解
- 【转载】设计之路:如何进行软件需求分析?