70分求助
查看原帖
70分求助
190314
lixiaoqian楼主2022/9/28 23:41
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std ;
const int N=200010 ;
int e[N],ne[N],h[N],idx ;
bool rev[N] ;
int n,k ;
inline void add(int a,int b) { e[idx]=b,ne[idx]=h[a],h[a]=idx++ ; }
int ans[2] ;
int dis[N],path[N] ;
inline int len()
{
    queue<int> q ;
    q.push(1) ;
    memset(dis,-0x3f,sizeof dis) ;
    dis[1]=0 ;
    while(q.size())
    {
        int t=q.front() ;
        q.pop() ;
        for(int i=h[t];~i;i=ne[i])
        {
            int j=e[i] ;
            if(dis[j]>-1e9) continue ;
            dis[j]=dis[t]+(rev[i]?-1:1) ;
            // if(cnt) printf("%d %d\n",j,dis[j]) ;
            // printf("--%d %d\n",j,dis[j]) ;
            q.push(j) ;
        }
    }
    int pos1=1 ;
    for(int i=1;i<=n;i++) if(dis[pos1]<dis[i]) pos1=i ;
    memset(dis,-0x3f,sizeof dis) ;
    memset(path,0,sizeof path) ;
    dis[pos1]=0 ;
    q.push(pos1) ;
    // puts("--------------------------------") ;
    while(q.size())
    {
        int t=q.front() ;
        q.pop() ;
        for(int i=h[t];~i;i=ne[i])
        {
            int j=e[i] ;
            if(dis[j]>-1e9) continue ;
            dis[j]=dis[t]+(rev[i]?-1:1) ;
            // if(cnt) printf("%d %d\n",j,dis[j]) ;
            path[j]=i ;
            q.push(j) ;
        }
    }
    int pos2=1 ;
    for(int i=1;i<=n;i++) if(dis[pos2]<dis[i]) pos2=i ;
    // printf("-------- %d %d\n",pos1,pos2) ;
    for(int i=pos2;i!=pos1;i=e[path[i]^1])
    {
        rev[path[i]]=rev[path[i]^1]=true ;
        // printf("%d\n",i) ;
    }
    return dis[pos2] ;
}
int main()
{
    memset(h,-1,sizeof h) ;
    scanf("%d%d",&n,&k) ;
    for(int i=1;i<n;i++)
    {
        int a,b ;
        scanf("%d%d",&a,&b) ;
        add(a,b),add(b,a) ;
    }
    for(int i=0;i<k;i++) ans[i]=len() ;
    // printf("%d %d %d\n",n<<1,ans[0],ans[1]) ;
    printf("%d",(n<<1)-ans[0]-(k==1?1:ans[1])) ;
    return 0 ;
}

做法就是做直径 然后边权-1 然后再做一遍直径 但是只有70pts 求助

2022/9/28 23:41
加载中...