• 第九关——2.29模拟赛


    14:26:48 不想让 你为难,你不再需要给我个答案。——杨宗纬《空白格》   

    第一题 【NOIP2018模拟赛】刺客信条(AC)

    分四个情况,用一个并查集维护联通性

    sprt()用于算平方根

    #include<bits/stdc++.h>
    const int N=2002;
    using namespace std;
    char ch;
    struct sby{
        int x,y;
        double v;
    }t[N*N];
    int n,x[N],y[N],f[N],xx,yy,tot,ans;
    void add(int x,int y,double v)
    {
        t[++tot].x=x;
        t[tot].y=y;
        t[tot].v=v;
    }
    bool cmp(sby a,sby b){return a.v<b.v;}
    int ss(int x){return f[x]=(f[x]^x)?ss(f[x]):x;}
    int main()
    {
        cin>>xx>>yy>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>x[i]>>y[i];
            f[i]=i;
            add(n+1,i,y[i]);add(n+1,i,xx-x[i]);
            add(n+2,i,x[i]);add(n+2,i,yy-y[i]);
            for(int j=1;j<i;j++)
            add(i,j,sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(double)(y[i]-y[j])*(y[i]-y[j]))/2);
        }
        f[n+1]=n+1;f[n+2]=n+2;
        sort(t+1,t+1+tot,cmp);
        for(ans=1;ss(n+1)^ss(n+2);ans++)f[ss(t[ans].x)]=ss(t[ans].y);
        printf("%.2lf",t[ans-1].v);
        return 0;
    }

    第二题 【NOIP2018模拟赛】传送门 (portal)

    假设我们当前节点为i

    要么在当前节点设传送门,暴力走p,再传回来,很明显我们会从最深的那个叶子传回来。

    要么在p的子树中设传送门,暴力走这条边2次(下去1次,回来1次)

    a[i]表示i子树中到i最远的叶子。

    最后答案就是f[1]

    #include<bits/stdc++.h>
    #define N 1000005
    #define ll long long
    using namespace std;
    ll f[N],g[N],a[N],c[2*N],b[2*N],head[N],n,m,next[2*N];
    void add(int x,int y,int z){next[++m]=head[x];b[head[x]=m]=y;c[m]=z;}
    void dfs(int k,int o)
    {
        f[k]=0,g[k]=0;
        ll v=0;
        for(int i=head[k];i;i=next[i])
        {
            int p=b[i];
            if(p!=o)
            {
                dfs(p,k);
                g[k]=g[k]+2*c[i]+g[p];
                a[k]=max(a[k],a[p]+c[i]);
                f[k]=f[k]+min(2*c[i]+f[p],g[p]+c[i]-a[p]);
            }
        }
        return;
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<n;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z),add(y,x,z);
        }
        dfs(1,0);
        printf("%lld
    ",f[1]);
    }

     第三题【NOIP2018模拟赛】黑暗之魂(darksoul)

    代码繁琐。思想简单。
    求图的直径。
    环套树,记dis(x,y)为环上的点x到点y的最短路径。
    显然,给环定一个方向,求个前缀和。对于每个环上的点x,必有一个a[x],表示按照给定的方向走,第一个满足环长显然不递减。
    所以拿个线段树维护一下。一个区间加,一个区间减。

    #include<bits/stdc++.h>
    #define ll long long
    const int N=1e6+7;
    using namespace std;
    int n,cnt,cir,cc,tot,mid,head,tail,flag;
    int ls[N],ss[N],low[N],bb[N];
    bool vis[N];
    int id[N],q[N*2];
    ll ans,f[N*2],size[N*2],s[N*2],dis[N*2],sumdis;
    struct xz{
        int y,w,next;
    }g[N*2];
    struct sby{
        int x,y,w;
    }a[N];
    vector <int> wyb;
    void add(int x,int y,int w)
    {
        g[++cnt]=(xz){y,w,ls[x]};
        ls[x]=cnt;
    }
    void tarjan(int x,int fa)
    {
        ss[x]=low[x]=++cnt;
        vis[x]=1; wyb.push_back(x);
        for (int i=ls[x];i>0;i=g[i].next)
        {
            int y=g[i].y;
            if(y==fa) continue;
            if(!ss[y])
            {
                tarjan(y,x);
                low[x]=min(low[x],low[y]);
            }
            else
            {
                if(vis[y]) low[x]=min(low[x],ss[y]);
            }
        }
        if(low[x]==ss[x])
        {
            cc++;
            int y=0,flag=0;
            if (wyb.back()!=x) flag=1,cir=cc;
            while (y!=x)
            {
                y=wyb.back();
                wyb.pop_back();
                bb[y]=cc;
                vis[y]=0;
                if (flag) id[++tot]=y;
            }
        }
    }
    void dfs(int x,int fa)
    {
        ll max1=0,max2=0;
        for (int i=ls[x];i>0;i=g[i].next)
        {
            int y=g[i].y;
            if ((bb[y]==cir) || (y==fa)) continue;
            dfs(y,x);
            ll d=f[y]+g[i].w;
            if (d>max1)
            {
                max2=max1;
                max1=d;
            }
            else if (d>max2) max2=d;
        }
        ans=max(ans,max1+max2);
        f[x]=max1;
    }
    bool cmp(sby a,sby b)
    {
        if (a.x==b.x)
        {
            if (a.y==b.y) return a.w<b.w;
            return a.y<b.y;
        }
        return a.x<b.x;
    }
    int main()
    {
        cin>>n;
        for (int i=1;i<=n;i++)
        {
            cin>>a[i].x>>a[i].y>>a[i].w;
            if (a[i].x>a[i].y) 
            swap(a[i].x,a[i].y);
        }
        sort(a+1,a+n+1,cmp);   
        for(int i=1;i<=n;i++)
        {
            if(a[i].x==a[i].y) 
            flag=1;
            else
            {
                if((a[i].x==a[i-1].x)&&(a[i].y==a[i-1].y)) 
                flag=1;
                else
                {
                    add(a[i].x,a[i].y,a[i].w);
                    add(a[i].y,a[i].x,a[i].w);
                }
            }
        }       
        if (flag)
        {
            cir=1;
            dfs(1,0);
            printf("%lld",ans+1);
            return 0;
        }
        tarjan(1,0);
        for(int i=1;i<=tot;i++) 
        dfs(id[i],0),size[i]=f[id[i]];    
        for(int i=1;i<=tot;i++)
        {
            int d;
            if(i==1) d=id[tot];
            else d=id[i-1];
            for(int j=ls[id[i]];j>0;j=g[j].next)
            {
                if(g[j].y==d)
                {
                    dis[i]=(ll)g[j].w;
                    break;
                }
            }
        }    
        for(int i=tot+1;i<=2*tot;i++) 
        dis[i]=dis[i-tot],size[i]=size[i-tot];
        for(int i=1;i<=2*tot;i++) 
        s[i]=s[i-1]+dis[i];
        sumdis=s[tot];
        head=tail=1;
        q[head]=1;    
        for (int i=2;i<=2*tot;i++)
        {
            while ((head<=tail) && (s[i]-s[q[head]]>sumdis/2)) head++;
            if (head<=tail) ans=max(ans,size[i]+s[i]+size[q[head]]-s[q[head]]);
            while ((head<=tail) && (size[q[tail]]-s[q[tail]]<=size[i]-s[i])) tail--;
            q[++tail]=i;
        }    
        printf("%lld",ans+1);
        return 0;
    }
  • 相关阅读:
    asp.net :使用jquery 的ajax +WebService+json 实现无刷新去后台值
    如何清理数据库缓存
    如何在虚拟机中Linux+Oracle10gRAC安装
    ORA01031 权限不足存储过程中DBA 角色用户无法执行DDL
    如何查看存储过程执行计划
    如何查看执行计划
    如何使用tkprof
    C#位运算讲解与示例[转]
    C#中Invalidate() 方法
    如何创建强命名程序集, 如何查看强命名程序集的PublicKeyToken
  • 原文地址:https://www.cnblogs.com/wybxz/p/12391751.html
Copyright © 2020-2023  润新知