Div1 小A抓小B tarjan双连通分量缩点+dfs
来源:互联网 发布:编程 网页开发 编辑:程序博客网 时间:2024/06/06 07:42
题目描述
小A和小B在一个无向图G上进行一个游戏。图G是连通的,有n个点,n条边,无重边,无自环,结点编号为1~n。游戏开始前小A在结点x,小B在结点y(x≠y)。游戏开始后,小A和小B轮流进行移动(小A先移动),每次移动可以从当前结点移动到与当前结点相邻的某个结点。小A的目标是抓到小B(某一次移动之后小A与小B在同一个结点),小B的目标是不被小A抓到。两人都有图G的地图,并且知道对方在哪个结点,两人都采取最优策略,问小A是否能通过有限次移动抓到小B。
输入描述
第1行3个整数n、x、y
第2~n+1行每行2个整数u、v,代表u与v之间有边相连。
输出描述
若小A能通过有限次移动抓到小B,输出1,否则输出0。
数据范围
n≤100000
样例输入
10 2 41 21 32 41 55 61 75 86 93 108 10
样例输出
1
题解,这是一个树,并且这个树上存在且存在一个环。
1.当A和B之间距离为1或0的时候,直接输出1。
2.否则的话,当环的长度小于等于3的时候,直接输出1,因为B一定会被A捉到。
3.我们进行双连通分量的缩点,将环缩成一个点,下面我们判断,当A、B同属于一个环上的时候,直接输出0,因为B绕着环跑永远不会被捉到。
4.然后我们从环缩成的点开始进行dfs序遍历,得到每一个点到基环的距离,如果dis[belong[x]] + 1 <= dis[belong[y]]表明A距离基环更近,直接输出1,否则输出0.
代码:
#include <bits/stdc++.h>using namespace std;const int MAXN = 1e5+10;int head[MAXN];int cnt;struct edge{ int v; int next; int cost; }Es[MAXN<<1]; void init(){ cnt = 0; memset(head,-1,sizeof(head)); }inline void add_edge(int i,int j,int cost){ Es[cnt].v = j; Es[cnt].cost = cost; Es[cnt].next = head[i]; head[i] = cnt++; } int n,x,y;int DFN[MAXN],LOW[MAXN];int stk[MAXN],vis[MAXN],belong[MAXN];int idx,sccnum,tot;vector<int> scc[MAXN];void tarjan(int x,int fa){DFN[x] = LOW[x] = ++ tot;stk[++idx] = x;vis[x] = 1;for(int e = head[x];e != -1;e = Es[e].next){int v = Es[e].v;if(v == fa) continue;if(!DFN[v]){tarjan(v,x);LOW[x] = min(LOW[x],LOW[v]);}else if(vis[v]){LOW[x] = min(LOW[x],DFN[v]);}}if(DFN[x] == LOW[x]){++sccnum;int item;do{item = stk[idx--];belong[item] = sccnum;scc[sccnum].push_back(item);vis[item] = 0;}while(x != item);}}int dis[MAXN];int vis2[MAXN];void dfs(int x,int dep){dis[x] = dep;for(int i = 0;i < scc[x].size();++i){int u = scc[x][i];for(int e = head[u];e != -1;e = Es[e].next){int v = Es[e].v;if(!vis2[belong[v]]){vis2[belong[v]] = 1;dfs(belong[v],dep+1);}}}}int main(){init();scanf("%d%d%d",&n,&x,&y);if(x == y) {puts("1");return 0;}for(int i = 0;i < n;i++){int a,b;scanf("%d%d",&a,&b);add_edge(a,b,1);add_edge(b,a,1);}for(int e = head[x];e != -1;e = Es[e].next){int v = Es[e].v;if(v == y){puts("1");return 0;}}tarjan(1,0);int start = 0;for(int i = 1;i <= sccnum;i++){ if(scc[i].size() > 3){ start = i; }}if(!start){puts("1");return 0;}if(belong[x] == belong[y]){puts("0");return 0;}dfs(start,0);if(dis[belong[x]] + 1 <= dis[belong[y]]){puts("1");}else{puts("0");}return 0;}/*7 4 11 22 33 44 55 66 77 4*/
阅读全文
0 0
- Div1 小A抓小B tarjan双连通分量缩点+dfs
- 双连通分量-tarjan
- 双连通分量-tarjan
- 【tarjan求解双连通分量】
- [双连通分量] tarjan算法
- tarjan算法-双连通分量
- TARJAN的求双连通分量算法
- 点/边 双连通分量---Tarjan算法
- Tarjan双连通分量算法论文翻译
- POJ1523 SPF【点双连通分量】【Tarjan】
- tarjan算法之 边双连通分量
- tarjan求点的双连通分量
- BZOJ1123 BLO [Tarjan][点双连通分量]
- Tarjan算法求割,桥,块(点双连通分支),边双连通分支总结
- Tarjan三大算法之双连通分量(双连通分量)
- POJ3177【边双连通分量缩点】
- 【小明A+B】
- 小明A+B
- 通过网页Url,保存为图片
- 数据结构实验之查找三:树的种类统计------map映射
- 招聘岗位-Java开发-上海浦东
- 使用WebStorm创建/运行/调试React Native项目
- 最少拦截系统 HDU
- Div1 小A抓小B tarjan双连通分量缩点+dfs
- 线段树--hdu4027 Can you answer these queries?
- oozie安装及简单使用
- listView 的item滑动删除
- 剑指offer:平衡二叉树
- 数据结构与算法专题之查找与排序——交换类排序(冒泡、快排与归并)
- SQL笔记
- Java 线程池的理论与实践
- SpringBoot之启动加载数据 CommandLineRunner(G)