日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

树网的核(codevs 1167)

發(fā)布時(shí)間:2025/5/22 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 树网的核(codevs 1167) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題目描述?Description

【問題描述】
設(shè) T=(V, E, W) 是一個(gè)無圈且連通的無向圖(也稱為無根樹),每條邊帶有正整數(shù)的權(quán),我
們稱T 為樹網(wǎng)(treenetwork),其中V, E分別表示結(jié)點(diǎn)與邊的集合,W 表示各邊長度的集合,
并設(shè)T 有n個(gè)結(jié)點(diǎn)。
路徑:樹網(wǎng)中任何兩結(jié)點(diǎn)a,b 都存在唯一的一條簡單路徑,用d(a,b)表示以a,b 為端點(diǎn)的
路徑的長度,它是該路徑上各邊長度之和。我們稱d(a,b)為a,b 兩結(jié)點(diǎn)間的距離。
一點(diǎn)v到一條路徑P的距離為該點(diǎn)與P 上的最近的結(jié)點(diǎn)的距離:
d(v,P)=min{d(v,u),u 為路徑P 上的結(jié)點(diǎn)}。
樹網(wǎng)的直徑:樹網(wǎng)中最長的路徑稱為樹網(wǎng)的直徑。對(duì)于給定的樹網(wǎng)T,直徑不一定是唯一的,
但可以證明:各直徑的中點(diǎn)(不一定恰好是某個(gè)結(jié)點(diǎn),可能在某條邊的內(nèi)部)是唯一的,我們稱該
點(diǎn)為樹網(wǎng)的中心。
偏心距 ECC(F):樹網(wǎng)T 中距路徑F 最遠(yuǎn)的結(jié)點(diǎn)到路徑F 的距離,即
ECC(F ) = max{d(v, F ), v?V}。
任務(wù):對(duì)于給定的樹網(wǎng)T=(V, E,W)和非負(fù)整數(shù)s,求一個(gè)路徑F,它是某直徑上的一段路徑
(該路徑兩端均為樹網(wǎng)中的結(jié)點(diǎn)),其長度不超過s(可以等于s),使偏心距ECC(F)最小。我們
稱這個(gè)路徑為樹網(wǎng)T=(V,E,W)的核(Core)。必要時(shí),F 可以退化為某個(gè)結(jié)點(diǎn)。一般來說,在上
述定義下,核不一定只有一個(gè),但最小偏心距是唯一的。
下面的圖給出了樹網(wǎng)的一個(gè)實(shí)例。圖中,A-B 與A-C是兩條直徑,長度均為20。點(diǎn)W是樹網(wǎng)
的中心,EF邊的長度為5。如果指定s=11,則樹網(wǎng)的核為路徑DEFG(也可以取為路徑DEF),偏
心距為8。如果指定s=0(或s=1、s=2),則樹網(wǎng)的核為結(jié)點(diǎn)F,偏心距為12。

輸入描述?Input Description

第1 行,兩個(gè)正整數(shù)n和s,中間用一個(gè)空格隔開。其中n 為樹網(wǎng)結(jié)點(diǎn)的個(gè)數(shù),s為樹網(wǎng)的核
的長度的上界。設(shè)結(jié)點(diǎn)編號(hào)依次為1, 2, ..., n。
從第2 行到第n行,每行給出3 個(gè)用空格隔開的正整數(shù),依次表示每一條邊的兩個(gè)端點(diǎn)編號(hào)和
長度。例如,“2 4 7”表示連接結(jié)點(diǎn)2 與4 的邊的長度為7。

所給的數(shù)據(jù)都是正確的,不必檢驗(yàn)。

輸出描述?Output Description

輸出只有一個(gè)非負(fù)整數(shù),為指定意義下的最小偏心距

樣例輸入?Sample Input

【輸入樣例1】
5 2
1 2 5
2 3 2
2 4 4
2 5 3

【輸入樣例2】
8 6
1 3 2
2 3 2
3 4 6
4 5 3
4 6 4
4 7 2
7 8 3

樣例輸出?Sample Output

【輸出樣例1】

5

【輸出樣例1】

5

數(shù)據(jù)范圍及提示?Data Size & Hint

【限制】
40%的數(shù)據(jù)滿足:5<=n<=15
70%的數(shù)據(jù)滿足:5<=n<=80
100%的數(shù)據(jù)滿足:5<=n<=300, 0<=s<=1000。邊長度為不超過1000 的正整數(shù)

/*數(shù)據(jù)不大,所以按照題目要求去做就行了先floyed預(yù)處理出兩點(diǎn)間的距離,然后dfs求出直徑,最后搜索直徑上的每條路徑(很明顯在小于s的情況下越長越好),用每條路徑中的答案更新ans 。 */ #include<cstdio> #include<iostream> #include<cstring> #define INF 100000000 #define M 310 using namespace std; int head[M],dis[M][M],a[M],vis[M],n,s,ans=INF; int cnt,maxn; struct node {int v,pre,t; };node e[M*2]; struct Node {int lu[M],len; };Node zh[M]; void add(int i,int x,int y,int z) {e[i].v=y;e[i].t=z;e[i].pre=head[x];head[x]=i; } void floyed() {for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(i!=j&&i!=k&&j!=k)dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); } void find(int x,int t,int Dis) {for(int i=head[x];i;i=e[i].pre)if(!vis[e[i].v]){vis[e[i].v]=1;a[t]=e[i].v;find(e[i].v,t+1,Dis+e[i].t);vis[e[i].v]=0;}if(Dis>=maxn){if(Dis>maxn)cnt=1,maxn=Dis;else cnt++;zh[cnt].len=t;for(int i=1;i<=t;i++)zh[cnt].lu[i]=a[i];} } void check(int t) {int ecc=0;for(int i=1;i<=n;i++)if(!vis[i]){int p=INF;for(int j=1;j<=t;j++)p=min(p,dis[i][a[j]]);ecc=max(p,ecc);}ans=min(ans,ecc); } void dfs(int i,int j,int t,int Dis) {if(j==zh[i].len){check(t);return;}if(Dis+dis[zh[i].lu[j]][zh[i].lu[j+1]]>s){check(t-1);return;}if(j<zh[i].len){vis[zh[i].lu[j+1]]=1;a[t]=zh[i].lu[j+1];dfs(i,j+1,t+1,Dis+dis[zh[i].lu[j]][zh[i].lu[j+1]]);} } int main() {memset(dis,0x3f3f3f3f,sizeof(dis));scanf("%d%d",&n,&s);for(int i=1;i<n;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);add(i*2-1,x,y,z);add(i*2,y,x,z);dis[x][y]=dis[y][x]=z;}floyed();//求兩點(diǎn)間距離 for(int i=1;i<=n;i++)//找出直徑 {memset(vis,0,sizeof(vis));vis[i]=1;a[1]=i;find(i,2,0);}for(int i=1;i<=cnt;i++)//搜索直徑上的每條路徑 {for(int j=1;j<=zh[i].len;j++){memset(vis,0,sizeof(vis));vis[zh[i].lu[j]]=1;a[1]=zh[i].lu[j];dfs(i,j,2,0);}}printf("%d",ans);return 0; } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/harden/p/5895533.html

總結(jié)

以上是生活随笔為你收集整理的树网的核(codevs 1167)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。