zoukankan      html  css  js  c++  java
  • 【好题】二分图构造+bfs+拆绝对值——UCF 2016 K

    /*
    首先想到拆绝对值
        ta-tb = ha-hb
        ta+tb = ha+hb
    可以发现,两个特征值之差/和 相等的点可以互相跳跃
    那么构造出一幅二分图,左边是所有特征值之差,右边是所有特征值之和,每个点(除结点1外)代表了一条边
     要求的结果,显然是从结点1的和|差一直到达结点n的和|差所经过的结点个数
     因为每次在点上转换代表必须跳一下
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long 
    #define N 1000005
    
    int d[N],n,h[N],t[N],id,id1,id2,s1,s2;
    map<ll,int> mpl,mpr;
    vector<int>G[N];
     
    int main(){
        int T;cin>>T;
        for(int tt=1;tt<=T;tt++){
            mpl.clear();mpr.clear();id=0;
            memset(d,0,sizeof d);
            cin>>n;
            for(int i=1;i<=n;i++)scanf("%d",&t[i]);
            for(int i=1;i<=n;i++)scanf("%d",&h[i]);
            for(int i=1;i<=n;i++){
                ll sum=(ll)t[i]+h[i];
                if(mpl.count(sum)==0)mpl[sum]=++id; 
                ll dif=(ll)t[i]-h[i];
                if(mpr.count(dif)==0)mpr[dif]=++id;
            }
            for(int i=2;i<n;i++){//连边 
                ll sum=(ll)t[i]+h[i];
                ll dif=(ll)t[i]-h[i];
                int u=mpl[sum],v=mpr[dif];
                G[u].push_back(v);
                G[v].push_back(u);     
            } 
             
            s1=mpl[t[1]+h[1]];
            s2=mpr[t[1]-h[1]];//两个起点 
            id1=mpl[t[n]+h[n]];
            id2=mpr[t[n]-h[n]];//两个终点 
            
            queue<int>q;while(q.size())q.pop();
            q.push(s1);q.push(s2);
            d[s1]=d[s2]=1;
            while(q.size()){
                int u=q.front();q.pop();
                for(auto v:G[u]){
                    if(d[v])continue;
                    d[v]=d[u]+1;q.push(v);
                }    
            } 
            
            if(!d[id1] && !d[id2]){
                printf("Field #%d: -1
    
    ",tt);    
            }else if(!d[id1]){
                printf("Field #%d: %d
    
    ",tt,d[id2]);    
            }else if(!d[id2]){
                printf("Field #%d: %d
    
    ",tt,d[id1]);    
            }else {
                printf("Field #%d: %d
    
    ",tt,min(d[id1],d[id2]));    
            }
            
            for(int i=1;i<=id;i++)G[i].clear();
        }    
    } 
  • 相关阅读:
    c语言中统计字符串中数字出现的次数
    tyvj1294 小v的舞会
    tyvj1114 搭建双塔
    tyvj1193 括号序列
    tyvj1113 魔族密码
    tyvj1102 单词的划分
    tyvj1097 mm不哭
    tyvj1189 盖房子
    tyvj1098 任务安排
    tyvj1144 股票
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12599984.html
Copyright © 2011-2022 走看看