Codeforces - Team Rocket Rises Again

题目链接:Codeforces - Team Rocket Rises Again


很明显如果我们先跑一个最短路出来,我们把最短路上面的边单独拿出来建图。

然后就可以得到边全是最短路上面的边的新图。

根据题目定义我们可以发现,这个是支配树。

跑一次支配树取max即可。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
typedef long long LL;
const LL inf=0x3f3f3f3f3f3f3f3f;
const int N=8e5+10,M=N<<1;
int n,m,s,vis[N],mx;	LL d[N];
int head[N],nex[M],w[M],to[M],tot;
inline void ade(int a,int b,int c){
	to[++tot]=b; nex[tot]=head[a]; w[tot]=c; head[a]=tot;
}
inline void add(int a,int b,int c){ade(a,b,c);	ade(b,a,c);}
struct Dominate_tree{
	int cnt,tot;
	int head[N<<1],pre[N<<1],to[M<<1],nex[M<<1],lat[M],cdy[M];
	int bel[M],val[M],sdom[M],idom[M],res[M];
	int dfn[M],id[M],fa[M];
	inline void add(int *head,int a,int b){
		to[++tot]=b; nex[tot]=head[a]; head[a]=tot;
	}
	void dfs(int x){
		dfn[x]=++cnt;	id[cnt]=x;
		for(int i=head[x];i;i=nex[i]){
			if(dfn[to[i]])	continue;
			dfs(to[i]);	fa[to[i]]=x;
		}
	}
	int find(int x){
		if(x==bel[x])	return x;
		int rt=find(bel[x]);
		if(dfn[sdom[val[bel[x]]]]<dfn[sdom[val[x]]])	val[x]=val[bel[x]];
		return bel[x]=rt;
	}
	void Tarjan(){
		for(int i=cnt;i>=1;i--){
			int x=id[i];
			for(int j=pre[x];j;j=nex[j]){
				if(!dfn[to[j]])	continue;
				find(to[j]);
				if(dfn[sdom[val[to[j]]]]<dfn[sdom[x]])	sdom[x]=sdom[val[to[j]]];
			}
			add(lat,sdom[x],x);	bel[x]=fa[x]; x=fa[x];
			for(int j=lat[x];j;j=nex[j]){
				find(to[j]);
				if(sdom[val[to[j]]]==x)	idom[to[j]]=x;
				else	idom[to[j]]=val[to[j]];
			}
			lat[x]=0;
		}
		for(int i=1,x;i<=cnt;i++){
			x=id[i];
			if(idom[x]!=sdom[x])	idom[x]=idom[idom[x]];
		}
	}
	void dfs_res(int x){
		res[x]=1;
		for(int i=cdy[x];i;i=nex[i]){
			dfs_res(to[i]);	res[x]+=res[to[i]];
		}
		if(x!=s)	mx=max(mx,res[x]);
	}
	void work(){
		for(int i=1;i<=n;i++)	sdom[i]=bel[i]=val[i]=i;
		dfs(s);	Tarjan();	tot=0;
		for(int i=1;i<=n;i++)	if(idom[i])	add(cdy,idom[i],i);
		dfs_res(s);
	}
}dt;
void Dijkstra(){
	priority_queue<pair<LL,int> > q; q.push({0,s}); memset(d,0x3f,sizeof d); d[s]=0;
	while(q.size()){
		int u=q.top().second;	q.pop();
		if(vis[u])	continue;	vis[u]=1;
		for(int i=head[u];i;i=nex[i]){
			if(d[to[i]]>d[u]+w[i]){
				d[to[i]]=d[u]+w[i];	q.push({-d[to[i]],to[i]});
			}
		}
	}
}
void build_new_graph(){
	for(int i=1;i<=n;i++){
		for(int j=head[i];j;j=nex[j]){
			if(d[i]+w[j]==d[to[j]])	
				dt.add(dt.head,i,to[j]),dt.add(dt.pre,to[j],i);
		}
	}
}
signed main(){
	ios::sync_with_stdio(false),cin.tie(nullptr);
	cin>>n>>m>>s;
	for(int i=1,a,b,c;i<=m;i++)	cin>>a>>b>>c,add(a,b,c);
	Dijkstra();	build_new_graph(); dt.work();
	cout<<mx;
	return 0;
}
发布了553 篇原创文章 · 获赞 242 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104213616