D. Cow and Fields-1307-(最短路)

总结

添加一条边,让最短路最大化,肯定跑两次spfa,dis1[i]+1+dis2[j],但是k∈2e5,O(n2)枚举是肯定不可取的,只能降低时间复杂度,要么nlogn,要么n。
因为我们要保证max( dis1[i]+1+dis2[j] ),那么就要保证dis[i]到dis[j]距离最小,这样添加边,才能让最短路损失的最小
后面,我们也看一下别人的做法,是按照dis1[i]-dis2[i]的差值排序的。
const int N=2e5+5;
vector<int>G[N];
int dis1[N],dis2[N];
bool vis[N];
void spfa(int dis[],int x)
{
    memset(vis,0);
    queue<int>que;
    que.push(x);
    vis[x]=true;
    while(!que.empty())
    {
        int pos=que.front();
        que.pop();
        for(auto it:G[pos])
        {
            if(vis[it])
                continue;
            dis[it]=dis[pos]+1;
            que.push(it);
            vis[it]=true;
        }
    }
}
struct node
{
    int pos,value;
    bool operator<(const node &b)const
    {
        return value<b.value;
    }
};
signed main()
{
    IOS;
   // file();
    int n,m,k;
    cin>>n>>m>>k;
    vector<int>a(k);
    for(auto &it:a)
        cin>>it;
    while(m--)
    {
        int x,y;
        cin>>x>>y;
        G[x].pb(y);
        G[y].pb(x);
    }
    spfa(dis1,1);
    spfa(dis2,n);
    vector<node>vec;
    for(auto it:a)
    {
        vec.pb( {it,dis1[it]} );
    }
    sort(all(vec));
    int len=vec.size();
    int ans=0;
    for(int i=1;i<len;i++)
    {
        int temp=dis1[n];
        int x=vec[i-1].pos,y=vec[i].pos;
        temp=min(temp,dis1[x]+dis2[y]+1);
        temp=min(temp,dis1[y]+dis2[x]+1);
        ans=max(ans,temp);
    }
    cout<<ans<<endl;
    return 0;
}

你可能感兴趣的:(#,最短路)