Educational Codeforces Round 124 (Rated for Div. 2) C~D题

C. Fault-tolerant Network

题意

给定序列长度n,有上下两个序列a,b,每个序列的内部相邻的位置链接在一起,现在要新加一些边,保证无论删除两个序列中的哪一个位置,剩下的2 ∗ n − 1个数会在一个连通块内,新加一条a[i]到b[j]的边所需要花费为abs(a[i]-b[j]) ,问最小的代价

思路:

我们很容易得到,当初始呈现”环形“时,一定满足条件,即abs(a[1]-b[1])+abs(a[n]-b[n])abs(a[1]−b[1])+abs(a[n]−b[n])或abs(a[1]-b[n])+abs(a[n]-b[1])abs(a[1]−b[n])+abs(a[n]−b[1])

同时发现:
如果选择a b s ( a [ 1 ] − b [ 1 ] ) abs(a[1]-b[1])abs(a[1]−b[1])我们也可以再加上一条端点包括a [ n ] a[n]a[n]和一条端点包括b [ n ] b[n]b[n]的两条边
如果选择a b s ( a [ n ] − b [ n ] ) abs(a[n]-b[n])abs(a[n]−b[n])我们也可以再加上一条端点包括a [ 1 ] a[1]a[1]和一条端点包括b [ 3 ] b[3]b[3]的两条边
如果选择a b s ( a [ 1 ] − b [ n ] ) abs(a[1]-b[n])abs(a[1]−b[n])我们也可以再加上一条端点包括a [ n ] a[n]a[n]和一条端点包括b [ 1 ] b[1]b[1]的两条边
如果选择a b s ( a [ n ] − b [ 1 ] ) abs(a[n]-b[1])abs(a[n]−b[1])我们也可以再加上一条端点包括a [ 1 ] a[1]a[1]和一条端点包括b [ n ] b[n]b[n]的两条边

总之:两个序列的四角位置的点都需要作为某条新边的端点就行了 

#include <bits/stdc++.h>
using namespace std;

typedef  long long ll;
#define int long long
#define endl '\n'
const int  N=2e5+10,M=1e3+10,INF=1e9+10;
int n,T;
int a[N],b[N];
int sta[N],stb[N];
int mx[N];

signed main(){
    cin>>T;
    for(int t=1;t<=T;t++) {
        scanf("%lld",&n);
        for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
        for(ll i=1;i<=n;i++) scanf("%lld",&b[i]);
        mx[0]=min(abs(a[1]-b[1])+abs(a[n]-b[n]),abs(a[1]-b[n])+abs(a[n]-b[1]));
        mx[1]=mx[2]=mx[3]=mx[4]=1e18;
        for(ll i=1;i<=n;i++){
            mx[1]=min(mx[1],abs(a[1]-b[i]));
            mx[2]=min(mx[2],abs(a[n]-b[i]));
            mx[3]=min(mx[3],abs(b[1]-a[i]));
            mx[4]=min(mx[4],abs(b[n]-a[i]));
        }
        ll ans=min(mx[0],mx[1]+mx[2]+mx[3]+mx[4]);
        ans=min(ans,abs(a[1]-b[1])+mx[2]+mx[4]);//a1连接b1
        ans=min(ans,abs(a[n]-b[n])+mx[1]+mx[3]);//an连接b1
        ans=min(ans,abs(a[1]-b[n])+mx[2]+mx[3]);//a1连接bn
        ans=min(ans,abs(a[n]-b[1])+mx[1]+mx[4]);//an连接b1
        printf("%lld\n",ans);
    }
    return 0;
}

 

 

posted @ 2022-03-12 14:25  怀义💭🚀🎈  阅读(30)  评论(0)    收藏  举报