BZOJ4016 最短路徑樹問題

2022-03-03 07:31:01 字數 2345 閱讀 7997

給乙個包含n個點,m條邊的無向連通圖。從頂點1出發,往其餘所有點分別走一次並返回。

往某乙個點走時,選擇總長度最短的路徑走。若有多條長度最短的路徑,則選擇經過的頂點序列字典序最小的那條路徑(如路徑a為1,32,11,路徑b為1,3,2,11,路徑b字典序較小。注意是序列的字典序的最小,而非路徑中節點編號相連的字串字典序最小)。到達該點後按原路返回,然後往其他點走,直到所有點都走過。

可以知道,經過的邊會構成一棵最短路徑樹。請問,在這棵最短路徑樹上,最長的包含k個點的簡單路徑長度為多長?長度為該最長長度的不同路徑有多少條?

這裡的簡單路徑是指:對於乙個點最多隻經過一次的路徑。不同路徑是指路徑兩端端點至少有乙個不同,點a到點b的路徑和點b到點a視為同一條路徑。

第一行輸入三個正整數n,m,k,表示有n個點m條邊,要求的路徑需要經過k個點。接下來輸入m行,每行三個正整數ai,bi,ci(1<=ai,bi<=n,1<=ci<=10000),表示ai和bi間有一條長度為ci的邊。資料保證輸入的是連通的無向圖。

輸出一行兩個整數,以乙個空格隔開,第乙個整數表示包含k個點的路徑最長為多長,第二個整數表示這樣的不同的最長路徑有多少條。

6 6 4

1 2 1

2 3 1

3 4 1

2 5 1

3 6 1

5 6 1

3 4對於所有資料n<=30000,m<=60000,2<=k<=n。

資料保證最短路徑樹上至少存在一條長度為k的路徑。

2016.12.7新加資料一組by - wyx-150137

首先我們先建立最短路徑樹(dijkstra+dfs),讓後對最短路徑樹做點分治,f[i][j][2]:表示前i個子樹到根節點距離為j 

對與新加的子樹,做一邊相同操作後,更新f即可.

#includeusing

namespace

std;

#define pi acos(-1.0)

#define pii pair#define mkp make_pairtypedef

long

long

ll;const

int inf=0x3f3f3f3f

;const

int maxn=60010

;int

n,m,k;

vector

v[maxn];

inthead[maxn],h[maxn],vis[maxn],fa[maxn],cnt1,cnt;

int f[maxn][2],g[maxn][2

];int

dis[maxn],deep[maxn];

intrt,sum,s,mx[maxn],size[maxn];

intans1,ans2;

struct

edge edge[maxn

<<1],e[maxn<<1

];void addedge(int u,int v,int

w)void addedge1(int u,int v,int

w)void

dijkstra()}}

}void dfs(int

u) }

}void getroot(int

u) }

mx[u]=max(mx[u],sum-size[u]);

if(mx[u]u;

}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 j=h[x];~j;j=e[j].nxt)

}}int

main()

cnt=cnt1=ans1=0

; memset(head,-1,sizeof

(head));

memset(h,-1,sizeof

(h));

memset(vis,

0,sizeof

(vis));

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

dijkstra();

dfs(1);

memset(vis,

0,sizeof

(vis));

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

getroot(1);

solve(rt,sum);

printf(

"%d %d\n

",ans1,ans2);

return0;

}

view code

BZOJ4016 最短路徑樹問題

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

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

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

最短路 最短路徑問題

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