• 【UOJ#236】[IOI2016]railroad(欧拉回路,最小生成树)


    【UOJ#236】[IOI2016]railroad(欧拉回路,最小生成树)

    题面

    UOJ

    题解

    把速度看成点,给定的路段看成边,那么现在就有了若干边,然后现在要补上若干边,以及一条([inf,)使得原图存在欧拉回路,那么就变成了求从大往小连边的边长的最小值。
    而欧拉回路每个点被来回覆盖的次数左右一定是一样的,假设向右-向左覆盖的次数为(g_i),那么如果(g_i>0),花费(1)的代价向(i-1)连边,如果(g_i>0),那么则可以不花费代价连边(i ightarrow i+1)
    看起来这样子得到了一个解,实际上欧拉回路还需要满足连通性,再求一遍(MST)把图连通就行了。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include"railroad.h"
    using namespace std;
    #define MAX 400200
    #define ll long long
    int S[MAX<<2],top,cnt,c[MAX];
    int f[MAX];int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
    struct Line{int u,v,w;}e[MAX];
    bool operator<(Line a,Line b){return a.w<b.w;}
    long long plan_roller_coaster(vector<int> s,vector<int> t)
    {
        int n=s.size();ll ans=0;
    	for(int i=0;i<n;++i)S[++top]=s[i],S[++top]=t[i];
    	S[++top]=-1e9-100;S[++top]=1e9+100;
    	sort(&S[1],&S[top+1]);top=unique(&S[1],&S[top+1])-S-1;
    	for(int &i:s)i=lower_bound(&S[1],&S[top+1],i)-S;
    	for(int &i:t)i=lower_bound(&S[1],&S[top+1],i)-S;
    	c[2]=-1;c[top]=1;for(int i=1;i<=top;++i)f[i]=i;
    	for(int i=0;i<n;++i)c[s[i]+1]++,c[t[i]+1]--;
    	for(int i=0;i<n;++i)f[getf(s[i])]=getf(t[i]);
    	for(int i=1;i<=top;++i)c[i]+=c[i-1];
    	for(int i=2;i<=top;++i)
    	{
    		if(c[i]==0)continue;
    		if(c[i]>0)ans+=1ll*c[i]*(S[i]-S[i-1]);
    		f[getf(i)]=getf(i-1);
    	}
    	for(int i=2;i<top-1;++i)if(getf(i)!=getf(i+1))e[++cnt]=(Line){i,i+1,S[i+1]-S[i]};
    	sort(&e[1],&e[cnt+1]);
    	for(int i=1;i<=cnt;++i)
    		if(getf(e[i].u)!=getf(e[i].v))
    			f[getf(e[i].u)]=getf(e[i].v),ans+=e[i].w;
    	return ans;
    }
    
  • 相关阅读:
    【Java】:Java当中为什么不能够直接用==比较String字符串
    Mybatis
    spring boot
    IDEA
    IDEA
    kafka集群partition分布原理分析(转发)
    kafka集群partition分布原理分析(转发)
    scons ------ 基本使用
    色彩管理中的Gamma值的理解
    SFUD ------ (Serial Flash Universal Driver) 串行 Flash 通用驱动库
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10462969.html
Copyright © 2020-2023  润新知