题目链接: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;
}