zoukankan      html  css  js  c++  java
  • Codeforces Round #621 (Div. 1 + Div. 2) D

    题意:

    给n,m,k,有n个点,m条线,距离都是一;

    有k个特殊点,选择其中两个,进行相连,距离变为1,使得原本的最短路,经过相连改变小或者不变,最终结果是所有结果里面的最大距离。

    思路:

    选择i,j两个点(满足从1出发先遇到 i ,在遇到 j ),1~i+j~n+1就是新的最短路(1~i表示 1 到 i 最短距离,j~n表示 j 到 n 最短距离)

    所以只要算出1到所有点的最短距离dis[0][N] 和 n到所有点的最短距离dis[1][N],再选择特殊点进行相连,因为最大化的话,肯定是要选择两个特殊点靠得近的排序

    同时,满足特殊点按照从1出发先遇到的顺序来,因为可能是先遇到 j 点,导致 会有1~i+j~n+1>1~j+i~n+1的情况

    比较就用1~i+j~n<1~j+i~n,然后操作有点像尺缩,叙述能力有限

    最后还要进行与1~n进行比较大小,这个用图解释比较直观

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define il inline
    #define it register int
    #define inf 0x3f3f3f3f
    #define lowbit(x) (x)&(-x)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define mod 998244353
    const int N=2e5+10;
    struct node{
        int v,next;
    }d[N<<1];
    struct node1{
        int x,bu;
        node1(){}
        node1(int xx,int buu):x(xx),bu(buu){}
        friend bool operator<(const node1 a,const node1 b){
            if(a.bu==b.bu){
                return a.x>b.x;
            }
            return a.bu>b.bu;
        }
    };
    int n,m,k;
    int a[N],head[N],tot;
    int dis[2][N];
    il void add(int u,int v){
        d[tot].v=v;d[tot].next=head[u];
        head[u]=tot++;
    }
    void bfs(int x,int c){
        dis[c][x]=0;
        priority_queue<node1>q;
        q.push(node1(x,0));
        while(!q.empty()){
            node1 t=q.top();q.pop();
            int u=t.x,bu=t.bu;
            for(it i=head[u];~i;i=d[i].next){
                int v=d[i].v;
                if(dis[c][v]==-1){
                    dis[c][v]=bu+1;
                    q.push(node1(v,bu+1));
                }
            }
        }
    }
    bool cmp(int x,int y){
        return dis[0][x]+dis[1][y]<dis[0][y]+dis[1][x];
    }
    int main(){
        tot=0;
        scanf("%d%d%d",&n,&m,&k);
        for(it i=0;i<=n;i++){head[i]=-1,dis[1][i]=dis[0][i]=-1;}
        for(it i=0;i<k;i++){
            scanf("%d",&a[i]);
        }
        for(it i=0;i<m;i++){
            int u,v;scanf("%d%d",&u,&v);
            add(u,v),add(v,u);
        }
        bfs(1,0);bfs(n,1);
        sort(a,a+k,cmp);
        int ans=dis[0][a[0]],da=-1;
        for(it i=1;i<k;i++){
            da=max(da,ans+dis[1][a[i]]+1);
            ans=max(ans,dis[0][a[i]]);
        }
        printf("%d
    ",min(dis[0][n],da));
        return 0;
    }
    /*
    5 5 2
    2 4
    1 5
    4 5
    3 4
    2 3
    1 2
    */
  • 相关阅读:
    PHP之Trait详解
    PHP中__call()方法与重载解析
    PHP Closure(闭包)类详解
    PHP 核心特性
    回调函数
    php的各种 I/O流 以及用法
    关于php的buffer(缓冲区)
    php的运行原理、cgi对比fastcgi以及php-cgi和php-fpm之间的联系区别
    低功耗设计入门(一)——低功耗设计目的与功耗的类型
    从CMOS到触发器(一)
  • 原文地址:https://www.cnblogs.com/luoyugongxi/p/12327170.html
Copyright © 2011-2022 走看看