BZOJ4016 最短路徑樹問題(點分治)

2021-08-07 08:50:23 字數 1359 閱讀 7558

題解:先跑乙個最短路圖,然後按照結點編號從小到大dfs一遍,dfs樹即為題目所要求。然後就是點分治的經典做法,路徑分為經過根節點的和不經過根節點的,不經過根節點的路徑一定屬於其某個子樹中,分治來做。

#include

#include

#include

#include

#include

#include

#include

#define inf 2000000000

#define pir pair

using

namespace

std;

int ans1,ans2,n,m,k,tot=0,rt,sum;

int dis[30005],head[30005],head2[30005],mx[30005],siz[30005],deep[30005],q[30005],fa[30005];

bool vis[30005]; int f[30005][2],g[30005][2];

priority_queuevector

,greater> hp;

struct edgeep[120005],e[60005];

vector

to[30005];

void insert(int x,int y,int val)

void insert2(int x,int y,int val)

void dj()}}

}void dfs(int now) //最短路圖上的dfs樹

}}void getroot(int now)

}mx[now]=max(mx[now],sum-mx[now]);

if (mx[now]void solve(int x,int s) }}

for (int j=1;j<=k;j++)

for (int j=1;j<=k;j++)}}

for (int j=0;j<=k;j++) f[j][0]=f[j][1]=0;

for (int i=head[x];i;i=e[i].ne)

}}int main()

for (int i=1;i<=n;i++)

dj();

tot=0; memset(vis,0,sizeof(vis));

dfs(1);

memset(vis,0,sizeof(vis));

rt=0,mx[0]=inf;sum=n;

getroot(1); solve(rt,sum);

printf("%d %d",ans1,ans2);

return

0;}

BZOJ4016 最短路徑樹問題

給乙個包含n個點,m條邊的無向連通圖。從頂點1出發,往其餘所有點分別走一次並返回。往某乙個點走時,選擇總長度最短的路徑走。若有多條長度最短的路徑,則選擇經過的頂點序列字典序最小的那條路徑 如路徑a為1,32,11,路徑b為1,3,2,11,路徑b字典序較小。注意是序列的字典序的最小,而非路徑中節點編...

BZOJ4016 最短路徑樹問題

給乙個包含n個點,m條邊的無向連通圖。從頂點1出發,往其餘所有點分別走一次並返回。往某乙個點走時,選擇總長度最短的路徑走。若有多條長度最短的路徑,則選擇經過的頂點序列字典序最小的那條路徑 如路徑a為1,32,11,路徑b為1,3,2,11,路徑b字典序較小。注意是序列的字典序的最小,而非路徑中節點編...

最短路 最短路徑問題

題目描述 平面上有n個點 n 100 每個點的座標均在 10000 10000之間。其中的一些點之間有連線。若有連線,則表示可從乙個點到達另乙個點,即兩點間有通路,通路的距離為兩點直線的距離。現在的任務是找出從一點到另一點之間的最短路徑。input 共有n m 3行,其中 第一行為乙個整數n。第2行...