首页 > 其他分享 >[ABC318G] Typical Path Problem 题解

[ABC318G] Typical Path Problem 题解

时间:2023-12-19 12:23:28浏览次数:31  
标签:ABC318G head int 题解 Head MAXN low Path now

原题链接:ABC318G

显然是圆方树。

点双缩点过后建立一颗以点 \(c\) 为根节点的圆方树,考虑什么情况是合法的。

从点 \(a\) 开始往上跳直到跳到点 \(c\),如果中间走过了某一个方点并且这个方点与 \(b\) 点有直接连边,那么就是合法的;否则不合法。

证明:如果路径中所经过的方点和 \(b\) 点有直接连边的话,那就说明了点 \(b\) 和路径上的一个点在同一个点双连通分量当中。所以一定可以通过一种路径来实现经过 \(b\) 点。

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 0x3f
#define inf_db 127
#define ls id << 1
#define rs id << 1 | 1
#define re register 
#define endl '\n'
typedef pair <int,int> pii;
const int MAXN = 1e6 + 10;
int n,m,head[MAXN],cnt,x,y,root,a,b,c,Cnt,Head[MAXN],fa[MAXN];
int dfn[MAXN],low[MAXN],id[MAXN],dcc_cnt,timestamp;
vector <int> dcc[MAXN];
struct Node
{
	int u,v,nxt;
}e[MAXN];
struct Edge
{
	int u,v,nxt;
}g[MAXN];
inline void Add(int u,int v){e[++cnt] = {u,v,head[u]};head[u] = cnt;}
inline void add(int u,int v){g[++Cnt] = {u,v,Head[u]};Head[u] = Cnt;}
stack <int> s; 
inline void Tarjan(int u,int father)
{
	dfn[u] = low[u] = ++timestamp;
	s.push(u);int son = 0;
	for(int i = head[u]; ~ i;i = e[i].nxt)
	{
		int now = e[i].v;
		if(!dfn[now])
		{
			Tarjan(now,u),low[u] = min(low[u],low[now]),son++;
			if(dfn[u] <= low[now])
			{
				int y;dcc_cnt++;
				do
				{
					y = s.top();s.pop();
					id[y] = dcc_cnt;
					dcc[dcc_cnt].push_back(y);
				}while(y != now);	
				dcc[dcc_cnt].push_back(u);
			}
		}
		else if(now != father) low[u] = min(low[u],dfn[now]);
	}
	if(son == 0 && u == root) dcc[++dcc_cnt].push_back(u);
}
inline void Dfs(int u,int father)
{
	fa[u] = father;
	for(int i = Head[u]; ~ i;i = g[i].nxt)
	{
		int now = g[i].v;
		if(now == father) continue;
		Dfs(now,u);
	}
}
inline bool Check(int u)
{
	for(int i = u;i != c;i = fa[i]) 
		if(i > n) for(int j = Head[i]; ~ j;j = g[j].nxt) if(b == g[j].v) return true;	
	return false;
}
signed main()
{
	memset(head,-1,sizeof head);
	memset(Head,-1,sizeof Head);
	cin >> n >> m >> a >> b >> c;
	for(int i = 1;i <= m;i++) cin >> x >> y,Add(x,y),Add(y,x);
	for(root = 1;root <= n;root++) if(!dfn[root]) Tarjan(root,0);
	int num = n;
	for(int i = 1;i <= dcc_cnt;i++)
	{
		int k = ++num;
		for(int j = 0;j < dcc[i].size();j++) add(k,dcc[i][j]),add(dcc[i][j],k);
	}
	Dfs(c,0);
	cout << (Check(a) ? "Yes" : "No");
	return 0;
}

标签:ABC318G,head,int,题解,Head,MAXN,low,Path,now
From: https://www.cnblogs.com/Creeperl/p/17913437.html

相关文章

  • [ABC318F] Octopus 题解
    前言赛时只做到了E题,赛后才来补的F题,还没做出来,看来还是我太菜了。看了题解过后感觉这道题的思路特别巧妙,于是就来写了这篇题解。题意简述一下题意。有\(n\)个宝藏位置分别在\(a_{i}\),另外有一只章鱼有\(n\)条触手,每条触手的长度为\(b_{i}\)。求有多少个点\(k\)......
  • Two-Colored Dominoes 题解
    前言看了这道题的几篇题解,感觉讲的方法都比较麻烦,这里讲一个感觉比较简单的方法。思路首先判断是否有解。计算一下每一行和每一列的牌的数量,只要有一个是奇数就无解,否则有解。证明显然,偶数一定可以分成两组,在纸上模拟一下也可以得出。其次看如何构造。对于竖着的牌,显然只对每......
  • P3071 [USACO13JAN] Seating G 题解
    题意:维护两个操作,区间推平,求连续\(0\)的个数为\(x\)的最前位置。线段树。因为需要求连续\(0\)的个数,所以维护区间左边连续\(0\)的最大个数,区间右边连续\(0\)的最大个数以及区间连续\(0\)的最大个数。注意修改的时候要看是修改为\(1\)还是修改为\(0\)。查询的时......
  • P2664 树上游戏 题解
    原题链接:P2664。题意:给定一棵树,每个点都有一个颜色\(c_{i}\)。对于每一个点\(i\),求出\(\sum_{j=1}^{n}s(i,j)\)的值。其中\(s(i,j)\)表示点\(i\)到点\(j\)的颜色数量。路径相关,考虑点分治。假设当前的重心为\(u\),那么对\(u\)自己的贡献就是\(u\)到\(u\)的所有......
  • [ABC328F] Good Set Query 题解
    复习了一下边带权并查集板子。设\(d_{x}\)表示当前点到它所在连通块根节点的距离。合并点\(x\)和点\(y\)所在两个连通块时需要更新\(d\)。因为将\(x\)点所在连通块的根节点的父亲节点设为了\(y\)点所在连通块的根节点,所以有\(x\toy\toFind(y)=x\toFind(x)\to......
  • P6370 [COCI2006-2007#6] KAMEN 题解
    原题链接:P6370思路题意不多赘述。首先这道题的\(60\)分暴力很好打,直接按题目中的操作做即可,时间复杂度\(O(nr)\)。考虑优化暴力。我们会发现很多次石头的起始点为同一列的情况,其实每一次下落的轨迹是差不多的。具体来讲应该是第一次下落的轨迹一定包含了后面每一次的轨迹。......
  • P4786 [BalkanOI2018] Election 题解
    题意给定一个长度为\(n\)的字符串\(s\),有\(m\)个询问,每次询问最少需要删掉多少个字符才能使\(l\)到\(r\)组成的字符串当中的每一个前缀和后缀都满足C的数量不小于T的数量。思路因为要满足C的数量不小于T的数量,我们不妨设字符C的位置的值为\(1\),字符S的位......
  • P8386 [PA2021] Od deski do deski 题解
    显然是一道计数dp。dp状态应该是最难的一部分了,个人认为这种状态设计得比较巧妙。如果像我刚开始一样设\(dp_{i,j}\)表示序列中一共有\(i\)个数,序列最后一个数为\(j\)的合法方案数的话,那么方程就会变得很不好转移,因为我们不知道当前的\(j\)和之前的某些数能不能匹配上,......
  • C0328 【1005 C组】模拟测试 斜率 题解
    原题链接:斜率。题意在一个平面直角坐标系中,给定\(n\)个点的横纵坐标,求出哪两个点所构成的连线的斜率最接近\(\frac{P}{Q}\)。数据范围:\(n\le1000000\)。思路显然这是一道数学题,不能直接暴力去找答案。首先我们可以弱化一下题目,求出斜率最接近\(y=0\)即\(x\)轴的两......
  • Omkar and Akmar 题解
    题意:有一个\(n\)个点的环,以及两个人。每个人可以向环中任意一个位置放置一个\(A\)或者\(B\),但是相邻的位置不能相同,不能行动者输。问最终的局面有多少种。一个结论是:后手必胜。证明:最终肯定不可能出现两个连续的空格,否则一定可以在其中一个上填\(A\)或\(B\)。所以最多只......