Codeforces - Team Rocket Rises Again

Keywords: iOS

Title Link: Codeforces - Team Rocket Rises Again

It's obvious that if we run the shortest path first, we will take out the top edge of the shortest path and make a drawing separately.

Then we can get a new graph with all the edges on the shortest path.

According to the definition of the topic, we can find that this is the dominant tree.

Take max for one run.

AC Code:

#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;
}
528 original articles published, 242 praised, 30000 visited+
Private letter follow

Posted by wikstov on Fri, 07 Feb 2020 10:56:01 -0800