1. 程式人生 > >11.4 考試

11.4 考試

但是 abs 個人 return spa ring string algo lca

最近好爆炸啊,我已經做好隨時退役的準備了...

T1 kill

題意:

給一個集合點,n個人,m個怪,在一條直線上,n<=m,每人一個怪,每個怪只被打一次,問所有走的路程的最大值的最小值

大家覺得這個題好簡單啊,但是我怎麽覺得好難啊

於是我就打了一個貪心加反悔$O(n^2logn)$,因為數據水,對了9個點,T了一個點QAQ...

大佬們都打了$O(nlogn)$的優秀算法

先把人和怪都排序

二分ans

貪心選擇最左邊的怪..

好像也挺簡單

技術分享
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include 
<algorithm> #include <iostream> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define rint register int using namespace std; inline void read(int &x) { x=0; int ff=1; char q=getchar(); while(q<0||q>9) { if(q==-) ff=-1; q=getchar(); } while(q>=0
&&q<=9) x=x*10+q-0,q=getchar(); x*=ff; } inline void readll(ll &x) { x=0; int ff=1; char q=getchar(); while(q<0||q>9) { if(q==-) ff=-1; q=getchar(); } while(q>=0&&q<=9) x=x*10+q-0,q=getchar(); x*=ff; } const int N=5006; int n,m; ll S,p[N],q[N];
int check(ll x) { int i,l=1; for(i=1;i<=n;++i) { while( l<=m&&abs(p[i]-q[l])+abs(q[l]-S)>x ) ++l; if(l>m) return 0; ++l; } return 1; } ll work() { ll l=0,r=1e10,mid,ans=1e10; while(l<=r) { mid=(l+r)>>1; if(check(mid)) ans=mid,r=mid-1; else l=mid+1; } return ans; } int main(){ //freopen("T1.in","r",stdin); rint i; read(n); read(m); readll(S); for(i=1;i<=n;++i) readll(p[i]); for(i=1;i<=m;++i) readll(q[i]); sort(p+1,p+1+n); sort(q+1,q+1+m); printf("%lld\n",work()); }
T1

T2 beauty

題意:

n個節點的一棵樹,給2*K個關鍵點

求$\sum_{i|關鍵點}dis(u_i,v_i)$的最大值

又沒做出來,郁悶ing~~~

把問題轉化成 求LCA的深度之和最小值

考慮到一個節點,如果它的每一個兒子子樹中關鍵點的個數都<=$\frac{size_x}{2}$

那麽x這顆子樹中的關鍵點兩兩配對的LCA都可以是x

dfs一遍就行了

技術分享
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define rint register int
using namespace std;
inline void read(int &x)
{
    x=0; int ff=1; char q=getchar();
    while(q<0||q>9) { if(q==-) ff=-1; q=getchar(); }
    while(q>=0&&q<=9) x=x*10+q-0,q=getchar();
    x*=ff;
}
const int N=100006;
int first[N],nt[N<<1],ver[N<<1],e;
void addbian(int u,int v)
{
    ver[e]=v;
    nt[e]=first[u];
    first[u]=e++;
}

int n,K,op,allk;
int ans;
int ke[N];

int fa[N],size[N],dep[N];
void dfs1(int x)
{
    int i;
    for(i=first[x];i!=-1;i=nt[i])
        if(ver[i]!=fa[x])
        {
            fa[ver[i]]=x;
            dep[ver[i]]=dep[x]+1;
            dfs1(ver[i]);
            size[x]+=size[ver[i]];
        }
}

void dfs(int x,int le)
{
    //printf("x=%d le=%d size[x]=%d\n",x,le,size[x]);
    int i,id=0;
    for(i=first[x];i!=-1;i=nt[i])
        if(ver[i]!=fa[x]&&size[ver[i]]*2>size[x])
            id=ver[i];
    if(!id)
        ans-=(size[x]-le)*dep[x];
    else
    {
        if( (size[id]-le)*2<=size[x]-le )
            ans-=(size[x]-le)*dep[x];
        else
        {
            ans-=(size[x]-size[id])*2*dep[x];
            dfs(id,le+size[x]-size[id]);
        }
    }
}

int main(){
    
    //freopen("T2.in","r",stdin);
    //freopen("T2.out","w",stdout);
    
    rint i; int tin1,tin2;
    mem(first,-1);
    
    read(n); read(K); read(op);
    allk=K<<1;
    for(i=1;i<=allk;++i)
        read(ke[i]),size[ke[i]]=1;
    for(i=1;i<n;++i)
    {
        read(tin1); read(tin2);
        addbian(tin1,tin2);
        addbian(tin2,tin1);
    }
    fa[1]=-1; dfs1(1);
    for(i=1;i<=allk;++i)
        ans+=dep[ke[i]];
    dfs(1,0);
    printf("%d\n",ans);
}
T2

T3 weight

給一個n個點,m條邊的無向帶權圖,問每一條邊權值最大多少使得這條邊在所有的最小生成樹裏(數據不保證圖聯通)

考慮先把最小生成樹建出來

如果是樹邊,ans是兩個端點之間所有簡單路徑的最小值-1

對於非樹邊,ans是這條邊兩個端點間樹上邊的最大值-1

技術分享
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define rint register int
using namespace std;
inline void read(int &x)
{
    x=0; int ff=1; char q=getchar();
    while(q<0||q>9) { if(q==-) ff=-1; q=getchar(); }
    while(q>=0&&q<=9) x=x*10+q-0,q=getchar();
    x*=ff;
}
const int N=100006;
const int Inf=2e9;
int first[N],nt[N<<1],ver[N<<1],w[N<<1],id[N<<1],e;
void addbian(int u,int v,int _w,int _id)
{
    ver[e]=v; w[e]=_w; id[e]=_id;
    nt[e]=first[u];
    first[u]=e++;
}

struct HSDAS
{
    int first[N],nt[N<<1],ver[N<<1],e;
    void clear()
    {
        mem(first,-1);
    }
    void addbian(int u,int v)
    {
        ver[e]=v;
        nt[e]=first[u];
        first[u]=e++;
    }
}h;

struct JI
{
    int u,v,w,order;
    JI(){}
    JI(int _u,int _v,int _w,int _order)
    {
        u=_u; v=_v; w=_w; order=_order;
    }
    bool friend operator < (JI a,JI b)
    {
        return a.w<b.w;
    }
}ji[N];

int n,m,op;
bool isis[N],istree[N];
int uu[N],vv[N],ww[N];
int v[N],fan[N];

int mn[N<<2],mx[N<<2],laz[N<<2];
void pushdown(int x)
{
    if(laz[x]!=Inf)
    {
        if(laz[x<<1]>laz[x]) laz[x<<1]=laz[x];
        if(laz[x<<1|1]>laz[x]) laz[x<<1|1]=laz[x];
        if(mn[x<<1]>laz[x]) mn[x<<1]=laz[x];
        if(mn[x<<1|1]>laz[x]) mn[x<<1|1]=laz[x];
        laz[x]=Inf;
    }
}
void build(int l,int r,int x)
{
    laz[x]=Inf;
    if(l==r)
    {
        mn[x]=Inf; mx[x]=v[fan[l]];
        return ;
    }
    int mid=(l+r)>>1;
    build(l,mid,x<<1);
    build(mid+1,r,x<<1|1);
    mx[x]=max(mx[x<<1],mx[x<<1|1]);
}
void qqmax(int L,int R,int &an,int l,int r,int x)
{
    if(L<=l&&r<=R)
    {
        if(an<mx[x]) an=mx[x];
        return ;
    }
    int mid=(l+r)>>1;
    if(L<=mid) qqmax(L,R,an,l,mid,x<<1);
    if(mid<R) qqmax(L,R,an,mid+1,r,x<<1|1);
}
void qqmin(int pos,int &an,int l,int r,int x)
{
    if(l==r)
    {
        if(an>mn[x]) an=mn[x];
        return ;
    }
    pushdown(x);
    int mid=(l+r)>>1;
    if(pos<=mid) qqmin(pos,an,l,mid,x<<1);
    else qqmin(pos,an,mid+1,r,x<<1|1);
}
void modi(int L,int R,int vv,int l,int r,int x)
{
    if(L<=l&&r<=R)
    {
        if(mn[x]>vv) mn[x]=vv;
        if(laz[x]>vv) laz[x]=vv;
        return ;
    }
    pushdown(x);
    int mid=(l+r)>>1;
    if(L<=mid) modi(L,R,vv,l,mid,x<<1);
    if(mid<R) modi(L,R,vv,mid+1,r,x<<1|1);
    mn[x]=min(mn[x<<1],mn[x<<1|1]);
}

int fa[N],dep[N],size[N],son[N];
void dfs1(int x)
{
    size[x]=1;
    int i;
    //printf("x=%d\n",x);
    for(i=h.first[x];i!=-1;i=h.nt[i])
    {
        //printf("i=%d\n",i);
        isis[(i>>1)+1]=1;
        //printf("i=%d\n",i);
    }
    //printf("x=%d\n",x);
    for(i=first[x];i!=-1;i=nt[i])
        if(ver[i]!=fa[x])
        {
            fa[ver[i]]=x;
            dep[ver[i]]=dep[x]+1;
            v[ver[i]]=w[i];
            dfs1(ver[i]);
            size[x]+=size[ver[i]];
            if(size[son[x]]<size[ver[i]])
                son[x]=ver[i];
        }
}
int dfn[N],tim,top[N];
void dfs2(int x,int tp)
{
    top[x]=tp; dfn[x]=++tim;
    fan[tim]=x;
    if(son[x])
        dfs2(son[x],tp);
    int i;
    for(i=first[x];i!=-1;i=nt[i])
        if(ver[i]!=fa[x]&&ver[i]!=son[x])
            dfs2(ver[i],ver[i]);
}
void Modi(int x,int y,int vv)
{
    int fx=top[x],fy=top[y];
    while(fx!=fy)
    {
        if(dep[fx]<dep[fy])
            x^=y,y^=x,x^=y,
            fx^=fy,fy^=fx,fx^=fy;
        modi(dfn[fx],dfn[x],vv,1,n,1);
        x=fa[fx]; fx=top[x];
    }
    if(dep[x]>dep[y]) x^=y,y^=x,x^=y;
    if(x!=y) modi(dfn[x]+1,dfn[y],vv,1,n,1);
}
int QQMAX(int x,int y)
{
    int fx=top[x],fy=top[y],an=0;
    while(fx!=fy)
    {
        if(dep[fx]<dep[fy])
            x^=y,y^=x,x^=y,
            fx^=fy,fy^=fx,fx^=fy;
        qqmax(dfn[fx],dfn[x],an,1,n,1);
        x=fa[fx]; fx=top[x];
    }
    if(dep[x]>dep[y]) x^=y,y^=x,x^=y;
    if(x!=y) qqmax(dfn[x]+1,dfn[y],an,1,n,1);
    return an;
}

int bfa[N];
int fin(int x)
{
    if(bfa[x]==-1) return x;
    return bfa[x]=fin(bfa[x]);
}

void kru()
{
    sort(ji+1,ji+1+m);
    int x,y,nownum=0,i;
    for(i=1;i<=m;++i)
    {
        x=fin(ji[i].u); y=fin(ji[i].v);
        if(x!=y)
        {
            bfa[x]=y;
            istree[ji[i].order]=1;
            addbian(ji[i].u,ji[i].v,ji[i].w,ji[i].order);
            addbian(ji[i].v,ji[i].u,ji[i].w,ji[i].order);
            ++nownum;
        }
        if(nownum==n-1)
            break;
    }
}

int main(){
    
    //freopen("T3.in","r",stdin);
    
    rint i; int tt;
    
    h.clear();
    mem(bfa,-1);
    mem(first,-1);
    
    read(n); read(m); read(op);
    for(i=1;i<=m;++i)
    {
        read(uu[i]); read(vv[i]); read(ww[i]);
        ji[i]=JI(uu[i],vv[i],ww[i],i);
        h.addbian(uu[i],vv[i]);
        h.addbian(vv[i],uu[i]);
    }
    kru();
    fa[1]=-1; dfs1(1);
    dfs2(1,1);
    build(1,n,1);
    for(i=1;i<=m;++i)
        if(isis[i]&&!istree[i])
            Modi(uu[i],vv[i],ww[i]);
    for(i=1;i<=m;++i)
    {
        //printf("i=%d %d\n",i,(isis[i]?1:0));
        if(isis[i])
        {
            if(istree[i])
            {
                tt=Inf; qqmin(dfn[dep[uu[i]]>dep[vv[i]]?uu[i]:vv[i]],tt,1,n,1);
                if(tt==Inf) tt=0;
                --tt;
                printf("%d ",tt);
            }
            else
                printf("%d ",QQMAX(uu[i],vv[i])-1);
        }
        else
            puts("0");
    }
}
T3

11.4 考試