题面
https://www.luogu.org/problem/P2993
题解
// luogu-judger-enable-o2 #include<cstdio> #include<iostream> #include<cstring> #include<queue> #include<vector> #define ri register int #define N 30500 #define INF 10000000000007LL #define LL long long using namespace std; int n,m,k,cc=0; vector<int> to[N],t[N],len[N],l[N]; int siz[N],b[N],bb[N]; bool vis[N]; LL dis[N],av=0,ac=0,a[N],aa[N]; LL A(int x) { if (x>=0) return a[x]; else return -1000000007; } struct node{ int v; LL d; bool operator < (const node &rhs) const { if (d==rhs.d) return v>rhs.v; else return d>rhs.d; } }; void addedge(int x,int y,int z){ t[x].push_back(y); l[x].push_back(z); //t[y].push_back(x); l[y].push_back(z); } void dij() { for (ri i=1;i<=n;i++) dis[i]=INF; dis[1]=0; priority_queue<node> q; q.push((node){1,0}); while (!q.empty()) { int x=q.top().v; q.pop(); if (vis[x]) continue; vis[x]=1; for (ri i=0,ls=to[x].size();i<ls;i++) { int v=to[x][i]; if (dis[x]+len[x][i]<dis[v]) { dis[v]=dis[x]+len[x][i]; q.push((node){v,dis[v]}); } } } } void build() { memset(vis,0,sizeof(vis)); vis[1]=1; priority_queue<node> q; while (!q.empty()) q.pop(); q.push((node){1,0}); while (!q.empty()) { int x=q.top().v; q.pop(); for (ri i=0,ls=to[x].size();i<ls;i++) if (dis[to[x][i]]==dis[x]+len[x][i] && !vis[to[x][i]]) { //cout<<x<<" "<<to[x][i]<<endl; cc++; vis[to[x][i]]=1; addedge(x,to[x][i],len[x][i]); addedge(to[x][i],x,len[x][i]); q.push((node){to[x][i],dis[to[x][i]]}); } } } void findroot(int x,int ff,int &rt,int &rts,int tot) { int curs=0; siz[x]=1; for (ri i=0,ls=t[x].size();i<ls;i++) if (t[x][i]!=ff && !vis[t[x][i]]) { findroot(t[x][i],x,rt,rts,tot); if (siz[t[x][i]]>curs) curs=siz[t[x][i]]; siz[x]+=siz[t[x][i]]; } if (tot-siz[x]>curs) curs=tot-siz[x]; if (curs<rts) rts=curs,rt=x; } void tonji(int x,int ff,int d,LL w,int &maxd) { if (w>aa[d]) aa[d]=w,bb[d]=0; if (w==aa[d]) bb[d]++; if (d>maxd) maxd=d; for (ri i=0,ls=t[x].size();i<ls;i++) if (t[x][i]!=ff && !vis[t[x][i]]) tonji(t[x][i],x,d+1,w+l[x][i],maxd); } void cnt(int x,int ff,int &tot) { tot++; for (ri i=0,ls=t[x].size();i<ls;i++) if (t[x][i]!=ff && !vis[t[x][i]]) cnt(t[x][i],x,tot); } void solve(int x) { // a[x] d==x maxw value // b[x] d==x maxw times a[0]=0; b[0]=1; vis[x]=1; int md=0; for (ri i=0,ls=t[x].size();i<ls;i++) if (!vis[t[x][i]]) { int maxd=0; tonji(t[x][i],x,1,l[x][i],maxd); md=max(md,maxd); //printf("%d %d %d ",i,t[x][i],maxd); for (ri j=1;j<=maxd;j++) if (aa[j]+A(k-j-1)>av) av=aa[j]+A(k-j-1),ac=0; for (ri j=1;j<=maxd;j++) if (aa[j]+A(k-j-1)==av) { ac+=bb[j]*1LL*b[k-j-1]; //printf("x=%d s=%d aa[%d]=%lld a[%d]=%lld bb[%d]=%d b[%d]=%d ",x,t[x][i],j,aa[j],k-j-1,a[k-j-1],j,bb[j],k-j-1,b[k-j-1]); //cout<<x<<" "<<aa[j]<<" "<<a[k-j-1]<<" "<<bb[j]<<" "<<b[k-j-1]<<endl; } for (ri j=1;j<=maxd;j++) { if (aa[j]>a[j]) a[j]=aa[j],b[j]=0; if (aa[j]==a[j]) b[j]+=bb[j]; } for (ri j=1;j<=maxd;j++) aa[j]=0,bb[j]=0; } for (ri i=0;i<=md;i++) a[i]=0,b[i]=0; for (ri i=0,ls=t[x].size();i<ls;i++) if (!vis[t[x][i]]) { int tot=0; cnt(t[x][i],x,tot); int rt=-1,rts=tot; findroot(t[x][i],x,rt,rts,tot); solve(rt); } } void dianfen() { memset(vis,0,sizeof(vis)); int rt=-1,rts=n; findroot(1,1,rt,rts,n); solve(rt); } int main(){ int a,b,c; scanf("%d %d %d",&n,&m,&k); for (ri i=1;i<=m;i++) { scanf("%d %d %d",&a,&b,&c); to[a].push_back(b); len[a].push_back(c); to[b].push_back(a); len[b].push_back(c); } dij(); build(); dianfen(); printf("%lld %lld ",av,ac); }