題意:
在一棵樹上選出m條路徑,這些路徑不能共用任意一條邊
問這些路徑中最小的一條路最大是多少
這道題的部分分十分有意思,搞了一搞
第一種情況是m=1,即只選出一條最長的路徑
顯然是計算樹的直徑
int fa[n],ans=0;
int dfs1(int u)
ans=max(ans,sum1+sum2);
return sum1;
}
ans即為所求
第二種情況是地圖沒有分支,為一條鏈
那就是說在序列上面二分,很經典的題了
bool check(int x)
else now+=a[i];
} return d>=m;
}
第三種情況是菊花圖,所有的u=1
直接每次列舉最長加最短,次長加次短,……,統計最小值即可
if(juhua)//菊花圖直接判斷即可
sort(a+1,a+n,cmp);
int ans=0x3f3f3f3f;
for(register int i=1;i<=m;++i)
ans=min(ans,a[i]+a[2*m-i+1]);
printf("%d\n",ans);
return 0;
}
所以總的**是這樣
#include#define n 50005
#define mid ((l+r+1)>>1)
using namespace std;
int n,m,u,v,w;
struct edge
edge[n<<1];
int cnt=0,head[n];
inline void add_edge(int from,int to,int dis)
templateinline void read(t &res)
int fa[n],ans=0;
int dfs1(int u)
ans=max(ans,sum1+sum2);
return sum1;
}int a[n];
void dfs2(int u)
}bool check(int x)
else now+=a[i];
} return d>=m;
}bool cmp(int a,int b)
int main()
if(m==1)//只有一條路,算直徑
if(lian)//地圖是一條鏈,相當於序列二分答案
{ dfs2(1);
int l=1,r=sum;
while(l<=r)
{// cout《這麼寫的話就已經有55分了,價效比極高……
所以d1你就有了100+100+55=255的高分
剩下的時間可以拿來思考正解
正解其實也十分簡單,等會兒寫……
update:正解已遷移至這裡:點我
NOIP2018 賽道修建
noip2018 賽道修建 樹形結構不帶樹上演算法走典型。用 dfs 即可,考慮的方向不能脫離樹狀結構。即考慮一棵子樹中分出的路線一定是獨立的,而那些沒用的邊可以傳上去作為備選答案。再考慮乙個貪心,我們每次上傳最大的即可。includeusing namespace std namespace ae...
競賽題解 NOIP2018 賽道修建
額 考試的時候大概猜到正解,但是時間不夠了,不敢寫,就寫了騙分qwq 現在把坑填好了 copy from 洛谷 c 城將要舉辦一系列的賽車比賽。在比賽前,需要在城內修建 m 條賽道。c 城一共有 n 個路口,這些路口編號為 1,2,n 有 n 1 條適合於修建賽道的雙向通行的道路,每條道路連線著兩個...
P5021 賽道修建 NOIP2018
傳送門 考場上把暴力都打滿了,結果檔案輸入輸出寫錯了.當時時間很充裕,如果認真想想正解是可以想出來的.問你 長度最小的賽道長度的最大值 顯然二分答案 考慮如何判斷是否可行 顯然對於乙個節點,它最多只能向父親傳一條路徑長度 那麼其它路徑的合併只能在子樹間進行 貪心一波,如果一段路徑在子樹就可以合併出合...