假期计划 100pts 求调 球球了 悬赏关注
查看原帖
假期计划 100pts 求调 球球了 悬赏关注
501947
DengDuck鄧德楼主2023/2/23 17:23
#include<bits/stdc++.h>
using namespace std;
long long n,m,k,tot,x,y,f[2505][2505],s[2505],h[2505],ans,fi[2505],se[2505],th[2505],p[7],p2[7];
struct node
{
    long long v,nxt;
}a[30005];
void add(long long x,long long y)
{
    tot++;
    a[tot].v=y;
    a[tot].nxt=h[x];
    h[x]=tot;
}
queue<long long>q;
void bfs(long long x)
{
    f[x][x]=-1;
    while(!q.empty())q.pop();
    q.push(x);
    while(!q.empty())
    {
        long long t=q.front();
        q.pop();
        for(int i=h[t];i;i=a[i].nxt)
        {
            if(f[x][a[i].v]>f[x][t]+1)
            {
                f[x][a[i].v]=f[x][t]+1;
                q.push(a[i].v); 
            }
        }
    }
}
bool cmp(long long x,long long y)
{
    if(s[x]==s[y])
    {
        return x<y;
    }
    return s[x]>s[y];
}
int main()
{
    scanf("%lld%lld%lld",&n,&m,&k);
    memset(f,127,sizeof(f));
    for(int i=2;i<=n;i++)
    {
        scanf("%lld",&s[i]);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%lld%lld",&x,&y);
        add(y,x);
        add(x,y); 
    }
    for(int i=1;i<=n;i++)
    {
        bfs(i); 
    }
    for(int i=2;i<=n;i++)
    {
        for(int j=2;j<=n;j++)
        {
            if(i==j)continue;
            if(f[i][j]<=k&&f[1][j]<=k)
            {
                if(s[j]>s[fi[i]])
                {
                    th[i]=se[i];
                    se[i]=fi[i];
                    fi[i]=j;
                }
                else if(s[j]>s[se[i]])
                {
                    th[i]=se[i];
                    se[i]=j;                    
                }
                else if(s[j]>s[th[i]])
                {
                    th[i]=j;
                }

            }
        }
    //  cout<<fi[i]<<' '<<se[i]<<' '<<th[i]<<endl;
    }
    for(int i=2;i<=n;i++)
    { 
        if(fi[i]==0)continue; 
        for(int j=2;j<=n;j++)
        {
            if(i==j)continue;
            if(fi[j]==0)continue;
            if(f[i][j]>k)continue;
            long long mx=0;
            p[1]=fi[i];
            p[2]=se[i];
            p[3]=th[i];
            p2[1]=fi[j];
            p2[2]=se[j];
            p2[3]=th[j];
            for(int x=1;x<=3;x++)
            {
                if(p[x]==i||p[x]==j)continue;
                for(int y=1;y<=3;y++)
                {
                    if(p2[y]==i||p2[y]==j)continue;
                    if(p[x]==p2[y])continue;
                    mx=max(mx,s[p[x]]+s[p2[y]]);
                }
            }
            ans=max(ans,mx+s[i]+s[j]);
        }
    }
    printf("%lld",ans);
    return 0;
}

思路大概没问题。

用博客内容解释一下

讨论了一下只选3个点的情况,发现在选中一个点之后相当于给其他店附了权值,然后找最大和次大的。

4个点情况应该差不多,枚举中间两个点,再写个判断,感觉可行,于是开打

2023/2/23 17:23
加载中...