BZOJ 4016 [FJOI2014]最短路径树问题
题解:构建最短路树,然后在上面点分治
一开始构建的思路是错的但是在Loj上A了
到现在还不明白为什么在BZOJ上T了QWQ,留坑
不要以为自己想的是对的
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=200009;
const int oo=1000000000;
typedef pair<int,int> fuck;
int n,m,k;
int d[maxn];
int cntedge=0;
int head[maxn];
int to[maxn],nex[maxn],dist[maxn];
void Addedge(int x,int y,int z){
nex[++cntedge]=head[x];
to[cntedge]=y;
dist[cntedge]=z;
head[x]=cntedge;
}
vector<fuck>G[maxn];
struct HeapNode{
int v,mindist;
HeapNode(int x){
v=x;mindist=d[x];
}
bool operator < (const HeapNode &rhs) const{
return mindist>rhs.mindist;
}
};
priority_queue<HeapNode>q;
int caled[maxn];
void Dijkstra(){
for(int i=1;i<=n;++i)d[i]=oo;
d[1]=0;q.push(HeapNode(1));
while(!q.empty()){
HeapNode x=q.top();q.pop();
int u=x.v;
if(caled[u])continue;
caled[u]=1;
for(int i=head[u];i;i=nex[i]){
if(d[u]+dist[i]<d[to[i]]){
d[to[i]]=d[u]+dist[i];
q.push(HeapNode(to[i]));
}
}
}
}
int nowsiz,root;
int g[maxn],siz[maxn],dep[maxn];
int vis[maxn];
void Getroot(int x,int fa){
siz[x]=1;g[x]=0;
for(int i=head[x];i;i=nex[i]){
if(vis[to[i]])continue;
if(to[i]==fa)continue;
Getroot(to[i],x);
siz[x]+=siz[to[i]];
g[x]=max(g[x],siz[to[i]]);
}
g[x]=max(g[x],n-siz[x]);
if(g[x]<g[root])root=x;
}
int maxlen=0;
long long tot=0;
int Tong[maxn][2];
pair<int,int>P[maxn];
int cnt;
void Getdep(int x,int fa){
siz[x]=1;
dep[x]=dep[fa]+1;
++cnt;
P[cnt]=make_pair(dep[x],d[x]);
for(int i=head[x];i;i=nex[i]){
if(to[i]==fa)continue;
if(vis[to[i]])continue;
d[to[i]]=d[x]+dist[i];
Getdep(to[i],x);
siz[x]+=siz[to[i]];
}
}
void Cal(int x){
// printf("Soling %d\n",x);
int maxdep=0;
d[x]=0;dep[x]=1;
Tong[1][0]=0;
Tong[1][1]=1;
for(int i=head[x];i;i=nex[i]){
if(vis[to[i]])continue;
cnt=0;
d[to[i]]=dist[i];
Getdep(to[i],x);
// for(int j=1;j<=cnt;++j)cout<<P[j].first<<' '<<P[j].second<<endl;
for(int j=1;j<=cnt;++j){
int a=P[j].first;
int b=P[j].second;
maxdep=max(maxdep,a);
if(a>k)continue;
if(b+Tong[k-a+1][0]>maxlen){
maxlen=b+Tong[k-a+1][0];
tot=Tong[k-a+1][1];
}else if(b+Tong[k-a+1][0]==maxlen){
tot+=Tong[k-a+1][1];
}
}
for(int j=1;j<=cnt;++j){
int a=P[j].first;
int b=P[j].second;
if(Tong[a][0]<b){
Tong[a][0]=b;
Tong[a][1]=1;
}else if(Tong[a][0]==b){
Tong[a][1]++;
}
}
}
for(int i=0;i<=maxdep;++i)Tong[i][0]=0,Tong[i][1]=0;
// cout<<maxlen<<' '<<tot<<endl;
// exit(0);
}
void Sol(int x){
vis[x]=1;
Cal(x);
for(int i=head[x];i;i=nex[i]){
if(vis[to[i]])continue;
nowsiz=siz[to[i]];root=0;
Getroot(to[i],x);
Sol(root);
}
}
void Dfs(int x){
caled[x]=1;
for(int i=0;i<G[x].size();++i){
fuck e=G[x][i];
if(caled[e.first])continue;
Addedge(x,e.first,e.second);
Addedge(e.first,x,e.second);
Dfs(e.first);
}
}
int main(){
scanf("%d%d%d",&n,&m,&k);
while(m--){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
Addedge(x,y,z);
Addedge(y,x,z);
}
Dijkstra();
for(int u=1;u<=n;++u){
for(int i=head[u];i;i=nex[i]){
if(d[u]+dist[i]==d[to[i]]){
G[u].push_back(make_pair(to[i],dist[i]));
}
}
sort(G[u].begin(),G[u].end());
}
cntedge=0;
memset(caled,0,sizeof(caled));
memset(head,0,sizeof(head));
Dfs(1);
for(int i=0;i<=n;++i)Tong[i][0]=0,Tong[i][1]=0;
nowsiz=n;root=0;g[root]=oo;
Getroot(1,0);
Sol(root);
cout<<maxlen<<' '<<tot<<endl;
return 0;
}
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!

浙公网安备 33010602011771号