P2993最短路径树问题80pts求调
  • 板块学术版
  • 楼主Ericby666
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/12/21 12:06
  • 上次更新2024/12/21 15:50:49
查看原帖
P2993最短路径树问题80pts求调
1045911
Ericby666楼主2024/12/21 12:06

RT

#include<bits/stdc++.h>
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define fir first
#define sec second
using namespace std;
const int N=3e4+5,INF=2e9;
int n,m,k,rt,MX,SIZE,sz[N],maxp[N],dis[N],len[N],num[N],dis1[N],dis2[N],cnt,pre,res,ans1,ans2;
bool vis[N],viss[N],ot[N];
struct node{int to,val;};
struct tmp{int v,w;bool operator<(const tmp &x)const{return v<x.v;}};
vector<node>vee[N],ve[N];
void dijkstra(int s){
	priority_queue<pii,vector<pii >,greater<pii > >q;
	memset(dis,0x3f,sizeof dis);
	memset(vis,0,sizeof vis);
	q.push(mp(0,s));
	dis[s]=0;
	while(!q.empty()){
		int u=q.top().sec;
		q.pop();
		if(viss[u])continue;
		viss[u]=1;
		for(auto a:vee[u]){
			int v=a.to,w=a.val;
			if(dis[u]+w<dis[v]){
				dis[v]=dis[u]+w;
				if(!viss[v])q.push(mp(dis[v],v));
			}
		}
	}
}
void build(int u){
	vector<tmp>s;
	for(auto a:vee[u]){
		int v=a.to,w=a.val;
		if(dis[v]==dis[u]+w)s.pb({v,w});
	}
	sort(s.begin(),s.end());
	for(int i=0;i<s.size();i++)
		if(!ot[s[i].v]){
			ot[s[i].v]=1;
			ve[u].pb({s[i].v,s[i].w});
			ve[s[i].v].pb({u,s[i].w});
			build(s[i].v);
		}
}
void getroot(int u,int fa){
	sz[u]=1,maxp[u]=0;
	for(auto a:ve[u]){
		int v=a.to;
		if(vis[v] || v==fa)continue;
		sz[u]+=sz[v];
		maxp[u]=max(maxp[u],sz[v]);
	}
	maxp[u]=max(maxp[u],SIZE-sz[u]);
	if(maxp[u]<MX)MX=maxp[u],rt=u;
}
void getdis(int u,int fa,int dep1,int dep2){
	if(dep2>k)return;
	dis1[++cnt]=dep1,dis2[cnt]=dep2;
	for(auto a:ve[u]){
		int v=a.to,w=a.val;
		if(vis[u] || v==fa)continue;
		getdis(v,u,dep1+w,dep2+1);
	}
}
int solve(int u){
	cnt=res=0;
	for(int i=1;i<=n;i++)len[i]=num[i]=0;
	num[0]=1;
	for(auto a:ve[u]){
		int v=a.to,w=a.val;
		if(vis[v])continue;
		pre=cnt;
		getdis(v,u,w,1);
		for(int i=pre+1;i<=cnt;i++){
			if(len[k-dis2[i]-1]+dis1[i]>ans1)ans1=len[k-dis2[i]-1]+dis1[i],res=num[k-dis2[i]-1];
			else if(len[k-dis2[i]-1]+dis1[i]==ans1)res+=num[k-dis2[i]-1];
		}
		for(int i=pre+1;i<=cnt;i++){
			if(len[dis2[i]]==dis1[i])num[dis2[i]]++;
			if(len[dis2[i]]<dis1[i])num[dis2[i]]=1,len[dis2[i]]=dis1[i];
		}
	}
	return res;
}
void divide(int u){
	vis[u]=1;
	int x=ans1,y=solve(u);
	if(x!=ans1)ans2=y;
	else ans2+=y;
	for(auto a:ve[u]){
		int v=a.to;
		if(vis[v])continue;
		rt=0,MX=INF,SIZE=sz[v];
		getroot(v,0);
		divide(rt);
	}
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m>>k;
	for(int i=1;i<=m;i++){
		int u,v,w;
		cin>>u>>v>>w;
		vee[u].pb({v,w});
		vee[v].pb({u,w});
	}
	dijkstra(1);
	build(1);
	rt=0,MX=INF,SIZE=n;
	getroot(1,0);
	divide(rt);
	cout<<ans1<<' '<<ans2;
	return 0;
}
2024/12/21 12:06
加载中...