AtCoder Grand Contest 001 C Shorten Diameter
阿新 • • 發佈:2019-02-03
題意:給你一棵樹,問最少刪多少節點使得樹中最遠的兩點距離為k(刪完點後要保持樹的連通性);
根據題意,就是每次都刪葉子結點,我們可以列舉k長的樹的中點,對於k為偶數,列舉中點,對於奇數,列舉中間邊的中點;
求最小;
#include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> #define STD std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) using namespace std; const int maxn=1e4+10; struct point{ int u,to,next; }pt[maxn],pp[maxn]; int vis[maxn],head[maxn],s,a[2100][2100],q; void init() { q=0; memset(head,-1,sizeof(head)); memset(a,0,sizeof(a)); } void add(int u,int v) { pt[q].next=head[u]; pt[q].u=u; pt[q].to=v; head[u]=q++; } void dfs(int pre,int st,int dis) { for (int i=head[st];i!=-1;i=pt[i].next) { int to=pt[i].to; if (to!=pre) { a[s][to]=a[to][s]=dis; dfs(st,to,dis+1); } } } int main() { STD; int n,ans=0,k,u,v,w=0; init(); cin>>n>>k; for (int i=1;i<n;i++) { cin>>u>>v; add(u,v); add(v,u); pp[w].u=u; pp[w++].to=v; } for (int i=1;i<=n;i++) { s=i; dfs(0,i,1); } if (k%2==0) { int minn=0x3f3f3f3f; for (int i=1;i<=n;i++) { ans=0; for (int j=1;j<=n;j++) { if (j!=i) { if (2*a[j][i]>k) ans++; } } minn=min(ans,minn); } cout<<minn<<endl; } else { int minn=0x3f3f3f3f; k=k/2; for (int i=0;i<w;i++) { ans=0; for (int j=1;j<=n;j++) { if (a[j][pp[i].u]>k&&a[j][pp[i].to]>k) ans++; } minn=min(ans,minn); } cout<<minn<<endl; } return 0; }