CF1307D Cow and Fields

Cow and Fields

link

Solution

分别从1、n广搜,可以得到每个点在广搜树中的层数:d[i],dn[i],考虑加一条边(x,y),则新出现的路中,可能为最短路的是:min(d[x]+dn[y]-1,d[y]+dn[x]-1)。
又由\(d[x]+dn[y]-1 < d[y]+dn[x]-1\)\(d[x]-dn[x] < d[y]-dn[y]\) 那么按d[i]-dn[i]排序,之后,找到最大的 \(dn[i]+max_{j< i}(d[j])\),再与d[n]比较。
复杂度O(n*logn+m)

Code

#include<bits/stdc++.h>

using namespace std;

int n,m,k,f[200005],d[200005],sp[200005],dn[200005],vis[200005];
queue<int> q;
vector<int> head[200005],rs;

const int com1(const int &a,const int &b)
{
    return d[a]-dn[a]<d[b]-dn[b];
}

int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=k;i++)
    {
        int a;
        scanf("%d",&a);
        sp[i]=a;
    }
    for(int i=1;i<=m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        head[a].push_back(b);
        head[b].push_back(a);
    }
    d[1]=1;
    q.push(1);
    while(!q.empty())
    {
        int dg=q.front();
        q.pop();
        for(int i=0;i<head[dg].size();i++)
        {
            int v=head[dg][i];
            if(!d[v])
            {
                d[v]=d[dg]+1;
                f[v]=dg;
                q.push(v);
            }
        }
    }
    dn[n]=1;
    q.push(n);
    while(!q.empty())
    {
        int dg=q.front();
        q.pop();
        for(int i=0;i<head[dg].size();i++)
        {
            int v=head[dg][i];
            if(!dn[v])
            {
                dn[v]=dn[dg]+1;
                q.push(v);
            }
        }
    }
    sort(sp+1,sp+1+k,com1);
    int ans=0,mx=d[sp[1]];
    for(int i=2;i<=k;i++)
    {
        ans=max(ans,mx+dn[sp[i]]);
        mx=max(mx,d[sp[i]]);
    }
    printf("%d\n",min(ans-1,d[n]-1));
}

猜你喜欢

转载自www.cnblogs.com/LiqgNonqfu/p/12348812.html
今日推荐