P7276 送給好友的禮物 dp

2022-03-29 05:37:21 字數 980 閱讀 7479

\(n\)個點的一棵樹,\(k\)個關鍵點,兩個人從根出發分別走一段路徑回到根。要求每個關鍵點至少被乙個人經過,求最短時間。

相當於求兩個覆蓋所有關鍵點的聯通子圖,使得最大那棵最小。

樹上只留下關鍵點和它們的祖先節點,這樣就變為了所有點都要經過,也就是所有葉子都要經過。

然後比較顯然的結論是一定會按照\(dfs\)從小到大的順序走,所以可以直接\(dp\)。設\(f_\)表示兩個人分別走到\(i,j\),目前第二棵樹的大小為\(k\)時第一棵樹的最小大小。

注意轉移\(x->i\)的時候權值得是\(dis(\ lca(x,i),i\ )\),因為是聯通子圖上延伸下來一條路徑。

時間複雜度\(o(n^3)\)

因為是比賽的時候寫的**改的,所以比較醜。

#include#include#includeusing namespace std;

const int n=420;

struct nodea[n<<1];

int n,k,tot,num,ls[n],dep[n],f[n],lca[n][n],ans,dp[n][n][n],son[n];

bool mark[n];

void addl(int x,int y)

bool calc(int x,int fa)

return mark[x];

}void dfs(int x,int fa)

if(flag||x==1)son[++num]=x;

for(int i=ls[x];i;i=a[i].next)

return;

}int lca(int x,int y)

int dis(int x,int y)

int main()

}for(int i=0;i<=num;i++)

for(int j=0;j<=num;j++)

printf("%d\n",ans*2);

}

P7276 送給好友的禮物 dp

n nn個點的一棵樹,k kk個關鍵點,兩個人從根出發分別走一段路徑回到根。要求每個關鍵點至少被乙個人經過,求最短時間。相當於求兩個覆蓋所有關鍵點的聯通子圖,使得最大那棵最小。樹上只留下關鍵點和它們的祖先節點,這樣就變為了所有點都要經過,也就是所有葉子都要經過。然後比較顯然的結論是一定會按照dfs ...