首页 > 其他分享 >CF131D Subway 题解

CF131D Subway 题解

时间:2023-10-06 18:44:51浏览次数:38  
标签:low cnt 10000 int 题解 CF131D dfn Subway dis

题目传送门

前置知识

强连通分量 | 最短路

解法

考虑用 Tarjan 进行缩点,然后跑最短路。

  • 缩点:本题的缩点有些特殊,基于有向图缩点修改而得,因为是无向图,所以在 Tarjan 过程中要额外记录一下从何处转移过来,防止在同一处一直循环。
    • 基环树上找环还有其他方法,这里仅讲解使用 Tarjan 求解。
  • 最短路:因为缩完点后就形成了一棵树,且因为是无向图,环外任意一点到环上最短距离等同于环上到环外任意一点最短距离,所以接着以环缩成的点为起点跑单源最短路或 DFS 或 LCA 求解即可。本篇题解使用 Dijkstra 算法求单源最短路。
    • 用 LCA 有些杀鸡用牛刀了。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define sort stable_sort 
#define endl '\n'
struct node
{
	int nxt,to,w;
}e[10000];
int head[10000],u[10000],v[10000],dfn[10000],low[10000],ins[10000],c[10000],dis[10000],vis[10000],cnt=0,tot=0,ans=0,scc=0,rt=0;
stack<int>s;
void add(int u,int v)
{
	cnt++;
	e[cnt].nxt=head[u];
	e[cnt].to=v;
	e[cnt].w=1;
	head[u]=cnt;
}
void tarjan(int x,int fa)
{
	int i,k=0;
	tot++;
	dfn[x]=low[x]=tot;
	ins[x]=1;
	s.push(x);
	for(i=head[x];i!=0;i=e[i].nxt)
	{
		if(e[i].to!=fa)
		{
			if(dfn[e[i].to]==0)
			{
				tarjan(e[i].to,x);
				low[x]=min(low[x],low[e[i].to]);
			}
			else
			{
				if(ins[e[i].to]==1)
				{
					low[x]=min(low[x],dfn[e[i].to]);
				}
			}
		}
	}
	if(dfn[x]==low[x])
	{
		ans++;
		scc=0;
		while(x!=k)
		{
			k=s.top();
			ins[k]=0;
			c[k]=ans;
			scc++;
			s.pop();
		}
		if(scc>=2)
		{
			rt=ans;
		}
	}
}
void dijkstra(int s)
{
	int x,i;
	priority_queue<pair<int,int> >q;
	memset(dis,0x3f,sizeof(dis));
	dis[s]=0;
	q.push(make_pair(0,-s));
	while(q.empty()==0)
	{
		x=-q.top().second;
		q.pop();
		if(vis[x]==0)
		{
			vis[x]=1;
			for(i=head[x];i!=0;i=e[i].nxt)
			{
				if(dis[e[i].to]>dis[x]+e[i].w)
				{
					dis[e[i].to]=dis[x]+e[i].w;
					q.push(make_pair(-dis[e[i].to],-e[i].to));
				}
			}
		}
	}
}
int main()
{
	int n,i;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>u[i]>>v[i];
		add(u[i],v[i]);
		add(v[i],u[i]);
	}
	for(i=1;i<=n;i++)
	{
		if(dfn[i]==0)
		{
			tarjan(i,0);
		}
	}
	cnt=0;
	memset(e,0,sizeof(e));
	memset(head,0,sizeof(head));
	for(i=1;i<=n;i++)
	{
		if(c[u[i]]!=c[v[i]])
		{
			add(c[u[i]],c[v[i]]);
			add(c[v[i]],c[u[i]]);
		}
	}
	dijkstra(rt);
	for(i=1;i<=n;i++)
	{
		cout<<dis[c[i]]<<" ";
	}
	return 0;
}	 

后记

推销一下自己的 Tarjan 学习笔记

标签:low,cnt,10000,int,题解,CF131D,dfn,Subway,dis
From: https://www.cnblogs.com/The-Shadow-Dragon/p/17744821.html

相关文章

  • 题解: P6933
    题目传送门这道题我用的是二分答案,只不过这道题和一般的二分答案有些不同,是浮点数的二分答案。那自然和整数的二分答案有些不同,下面我会说到。我们先来看一下思路解法。思路解法首先确定了是二分答案,我们需要先确定初始的\(l\)和\(r\)和check函数。check函数好写,我们......
  • 【UVA 514】Rails 题解(栈+队列)
    PopPush市有一个著名的火车站。那个里的乡村是令人难以置信的丘陵。车站建于上世纪。不幸的是,当时资金极其有限。有可能仅建立表面轨迹。此外,事实证明,该站可能只是一个死胡同(见图片),由于缺乏可用空间,它只能有一个轨道。当地的传统是,每一列从A方向到达的火车都会继续朝A方向行驶......
  • 【题解 P4550】 收集邮票
    收集邮票题目描述有\(n\)种不同的邮票,皮皮想收集所有种类的邮票。唯一的收集方法是到同学凡凡那里购买,每次只能买一张,并且买到的邮票究竟是\(n\)种邮票中的哪一种是等概率的,概率均为\(1/n\)。但是由于凡凡也很喜欢邮票,所以皮皮购买第\(k\)次邮票需要支付\(k\)元钱。现......
  • neovim的插件管理器vim-plug导致代码颜色不显示问题解决
    neovim的帮助文件路径F:\Programs\Neovim\share\nvim\runtime\docruntimepath的帮助文档路径F:\Programs\Neovim\share\nvim\runtime\doc\options.txt$VIM环境变量$VIM被用来确定Vim中不同的用户文件的位置,比如用户启动脚本“.vimrc”。这个是系统设置,详见startup。允许每......
  • 关于洛谷题解审核
    我想问一下,大家觉得题解的重点是什么?很显然是思路,代码的正确性,次要的才是格式。但是,洛谷对于题解格式的审核是不是有点过于严格了呢?比如说这段话:如果\(n\)为\(0\),那么便是无解。大家能一眼看出,后面多了空格吗?这种题解其实没什么大问题,别人看题解时根本不会在意这些......
  • 【bitset】【线段树】CF633G Yash And Trees 题解
    CF633G简单题。先看到子树加和子树质数个数和,果断转换为dfs序进行处理。既然有区间求和,考虑线段树。若对于每一个节点维护一个\(cnt\)数组,用二进制数\(x\)来表示,即当\(cnt_i=1\)时第\(i\)位为\(1\)。设当前节点为\(u\),左右子节点分别为\(ls\)和\(rs\)。发现......
  • 【倍增】P3422 [POI2005]LOT-A Journey to Mars 题解
    P3422一道有点意思的题。看到是一个环,先破环为链,即\(a_{n+i}=a_i,b_{n+i}=b_i\),此时就只需要跳到\(x+n\)而无需判环了。如果顺时针走:令\(sum_i=\sum\limits_{j=1}^{i}{a_j-b_j}\),当能从\(x\)跳到\(x+n\)时,有\[sum_{x-1}\lesum_x,sum_{x-1}\lesum_{x+1},\dot......
  • 【DP】ABC273F Hammer 2 题解
    ABC273F一道比较板的区间\(\text{dp}\)。先对坐标离散化,令离散化数组为\(v\)。令\(f_{i,j}\)表示能走到区间\([v_i,v_j]\)的最短路程,显然\(f\)数组初始为\(inf\)。但发现这样无法转移,可以再增加一维\(k\in\{0,1\}\),表示此时在\([v_i,v_j]\)的\(v_i/v_j\)处。......
  • 【线段树合并】CF1805E There Should Be a Lot of Maximums 题解
    CF1805E待补:有另解看到维护树上问题,可以想到线段树合并。但直接维护显然不行,要一点技巧。发现\(val\)的出现次数\(cnt_{val}\)如果\(\ge3\),那么一定是一个候选项,若\(cnt_{val}=1\),那么一定不能作为候选项。于是可以用权值线段树维护对于\(val\)有\(cnt_{val}=......
  • [ABC257F] Teleporter Setting 题解
    1.题目洛谷传送门2.思路我们可以把不确定的点当成真实存在的\(0\)号点,建边的时候就正常连即可。然后我们来看一个样例:1-2-03-4-5当我们把\(0\)号点看成\(3\)号点时,答案就是\(1\)号点到\(0\)号点的距离加上\(3\)号点到\(5\)号点的距离。然后我们再......