首页 > 其他分享 >abc375_G

abc375_G

时间:2024-10-21 11:00:40浏览次数:1  
标签:ver int auto vector low abc375 id

G - Road Blocked 2

思路

只有当一条边是从\(1\)到\(n\)的所有最短路构成的图的桥时,去掉这条边,最短路才会变大

怎么判断一条边是否可以构成最短路呢,比如求\(1\)到\(n\)的最短路,分别求出dist1(源点为1)和distn(源点为n),当一条边(端点分别为a,b,边长为w)包含再最短路之中时,它满足如下条件

    dist1[n]=dist1[a]+w+distn[b]||dist1[n]=distn[a]+w+dist1[b]

当然还有其它方法,我写的代码就是其他方法,只是上面的方法更简单罢了

代码

struct Edge{
	int a,b,c;
};

void solve() {
	int n,m;
	cin>>n>>m;
	vector<vector<pii>> g(n+1);
	vector<Edge> es(m+1);
	for(int i=1;i<=m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		es[i]={a,b,c};
		g[a].push_back({b,i}),g[b].push_back({a,i});
	}
	vector<bool> st(n+1);
	vector<ll> dist(n+1,1ll<<60);
	priority_queue<pll,vector<pll>,greater<pll>> q;
	dist[1]=0;
	q.push({dist[1],1});

	vector<vector<pii>> pas(n+1);

	while(q.size()){
		auto [dis,ver]=q.top();
		q.pop();
		if(st[ver]) continue;
		st[ver]=true;
		for(auto [y,id]:g[ver]){
			int w=es[id].c;
			if(dist[y]>dis+w){
				pas[y].clear();
				pas[y].push_back({ver,id});
				dist[y]=dis+w;
				q.push({dist[y],y}); 
			}
			else if(dist[y]==dis+w){
				pas[y].push_back({ver,id});
			}
		}
	}
	vector<bool> st1(n+1);
	vector<vector<pii>> fg(n+1);
	auto dfs=[&](auto && self,int u)->void{
		if(st1[u]) return;
		st1[u]=true;
		for(auto [ver,id]:pas[u]){
			fg[u].push_back({ver,id}),fg[ver].push_back({u,id});
			self(self,ver);
		}
	};
	dfs(dfs,n);
	vector<int> dfn(n+1),low(n+1);
	vector<bool> fst(m+1);
	int timestamp=0;
	auto tarjan=[&](auto && self,int u,int fa)->void{
		dfn[u]=low[u]=++timestamp;
		for(auto [y,id]:fg[u]){
			if(!dfn[y]){
				self(self,y,u);
				low[u]=min(low[u],low[y]);
				if(low[y]>dfn[u]){
					fst[id]=true;
				}
			}
			else if(y!=fa){
				low[u]=min(low[u],dfn[y]);
			}
		}
	};
	tarjan(tarjan,1,0);
	for(int i=1;i<=m;i++){
		cout<<(fst[i]?"Yes":"No")<<endl;
	}
}

标签:ver,int,auto,vector,low,abc375,id
From: https://www.cnblogs.com/mgnisme/p/18488967

相关文章

  • [ABC375C] Spiral Rotation
    [ABC375C]SpiralRotation题意给出一个边长为偶数\(n\)的只由#和.组成的矩阵。你需要按顺序对于\(i=1,2,\cdots,\frac{n}{2}\)将满足\(i\lex,y\len+1-i\)的单元格\((y,n+1−x)\)替换成单元格\((x,y)\)的字符,问操作完后的矩阵。\(2\len\le3000\)。思路C题......
  • [ABC375D] ABA
    [ABC375D]ABA题意给出一个由大写字母组成的长度为\(n\)的字符串\(s\),问长度为\(3\)的回文子序列数量。思路考虑枚举子序列中间的字符,则两边的字符需要相等,可以预处理出位置\(i\)左边和右边字符\(c\)的数量\(L_{i,c}和R_{i,c}\),则根据乘法原理可知答案为:\[\sum_{......
  • ABC375
    E题目大意:\(n\)个人,每个人初始在第\(a_i\)组,有一个力量值\(b_i\)。需要调整某些人到其他组去,使得每个组的力量值相等。若能,求出最少调整的人数。若不能,输出\(-1\)。\(n\leq100,1\leqb_i,\sumb_i\leq1500,a_i\in\{1,2,3\}\)。分析:暴力dfs显然不行,还要求最少调整的人数,只能......
  • ABC375 Review
    ABC375ReviewAB模拟题过C很让人恼怒的一道题,思路一点也不难想,但是代码实现过于困难了(对于我来说)分析自己找一两组样例就会发现这道题实际上实在模拟一个矩阵不断向内旋转\(90°\)的过程,从外到里旋转的次数越来越多,旋转的过程可以发现实际上可以通过模\(4\)来进行简化......
  • 24/10/13 ABC375补题笔记
    A典,属于显而易见的水题,这数据范围直接暴力做就行了。#include<bits/stdc++.h>usingnamespacestd;intmain(){ intn; cin>>n; strings; cin>>s; intcnt=0; if(n<2)returncout<<0<<endl,0; for(inti=0;i<s.size()-2;i++)......
  • ABC375 (A~G) 题解
    也是补完整场了。(虽然只有一题要补A模拟。B模拟。C模拟。D模拟。EE-3TeamDivision还想了蛮久的。题意:有三个队伍,各有一些人,人有能力值,人可以换队伍。问三个队伍能力值相同最少需要让多少人交换队伍。人数\(\le100\),值域\(\le1500\)题目还是挺误导人的,如......
  • ABC375
    前言F、G没时间写了,主要是C太唐了,甚至没想到转两遍的只需要把转一遍的循环两边就行了,浪费太多时间,D因为C++20特殊性质CE了一发,E数组开小吃了一发罚时。A、B没啥好说的从C开始吧。C-SpiralRotation发现就是从歪往里数第多少层就是顺时针转多少圈,由此\(\mod4\)......