• BZOJ 1937 最小生成树


    KM的复杂度是不是又是迷啊。。。

    跑的好快

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxv 1750
    #define maxe 100050
    #define inf 2000000000
    using namespace std;
    int n,m,g[maxv],nume=1,x[maxv],y[maxv],w[maxv],p,q;
    int dis[maxv],anc[maxv][11],fath_e[maxv];
    int map[maxv][maxv],slack[maxv],linky[maxv],lx[maxv],ly[maxv];
    bool flag[maxv],visx[maxv],visy[maxv];
    struct edge
    {
        int v,w,id,nxt;
    }e[maxe];
    void addedge(int u,int v,int w,int id)
    {
        e[++nume].v=v;e[nume].w=w;
        e[nume].id=id;e[nume].nxt=g[u];g[u]=nume;
    }
    void dfs(int x)
    {
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v!=anc[x][0])
            {
                anc[v][0]=x;dis[v]=dis[x]+1;fath_e[v]=e[i].id;
                dfs(v);
            }
        }
    }
    void get_table()
    {
        for (int e=1;e<=10;e++)
            for (int i=1;i<=n;i++)
                anc[i][e]=anc[anc[i][e-1]][e-1];
    }
    int lca(int x,int y)
    {
        if (dis[x]<dis[y]) swap(x,y);
        for (int e=10;e>=0;e--)
        {
            if ((dis[anc[x][e]]>=dis[y]) && (anc[x][e]))
                x=anc[x][e];
        }
        if (x==y) return x;
        for (int e=10;e>=0;e--)
        {
            if (anc[x][e]!=anc[y][e])
            {
                x=anc[x][e];
                y=anc[y][e];
            }
        }
        return anc[x][0];
    }
    void build(int x,int pos,int id,int val)
    {
        while (x!=pos)
        {
            map[id][fath_e[x]]=max(w[fath_e[x]]-val,0);
            x=anc[x][0];
        }
    }
    bool hungary(int x)
    {
        visx[x]=true;
        for (int i=1;i<=m;i++)
        {
            if (visy[i]) continue;
            int t=lx[x]+ly[i]-map[x][i];
            if (!t)
            {
                visy[i]=true;
                if ((linky[i]==-1) || (hungary(linky[i])))
                {
                    linky[i]=x;
                    return true;
                }
            }
            else slack[i]=min(slack[i],t);
        }
        return false;
    }
    int KM()
    {
        for (int i=1;i<=m;i++) lx[i]=-inf,ly[i]=0,linky[i]=-1;
        for (int i=1;i<=m;i++)
            for (int j=1;j<=m;j++)
                lx[i]=max(lx[i],map[i][j]);
        for (int i=1;i<=m;i++)
        {
            for (int j=1;j<=m;j++) slack[j]=inf;
            for (;;)
            {
                memset(visx,false,sizeof(visx));
                memset(visy,false,sizeof(visy));
                if (hungary(i)) break;
                int mn=inf;
                for (int j=1;j<=m;j++) if (!visy[j]) mn=min(mn,slack[j]);
                for (int j=1;j<=m;j++)
                {
                    if (visx[j]) lx[j]-=mn;
                    if (visy[j]) ly[j]+=mn;
                    else slack[j]-=mn;
                }
            }
        }
        int ret=0;
        for (int i=1;i<=m;i++)
        {
            if (linky[i]==-1) continue;
            ret+=map[linky[i]][i];
        }
        return ret;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x[i],&y[i],&w[i]);
            if (x[i]>y[i]) swap(x[i],y[i]);
        }
        for (int i=1;i<n;i++)
        {
            scanf("%d%d",&p,&q);if (p>q) swap(p,q);
            for (int j=1;j<=m;j++)
            {
                if ((x[j]==p) && (y[j]==q))
                {
                    addedge(p,q,w[j],j);addedge(q,p,w[j],j);
                    flag[j]=true;break;    
                }    
            }
        }
        dfs(1);get_table();
        for (int i=1;i<=m;i++)
        {
            if (flag[i]) continue;
            int t=lca(x[i],y[i]);
            build(x[i],t,i,w[i]);
            build(y[i],t,i,w[i]);
        }
        printf("%d
    ",KM());
        return 0;
    }
  • 相关阅读:
    GKCTF2020
    PTA的Python练习题(二十三)
    Web刷题之旅(三)
    Web刷题之旅(二)
    Web刷题之旅(一)-攻防世界 站
    PTA的Python练习题(补)
    Ctfshow
    Ctfshow
    15、实操篇——Vi和Vim编译器
    13、14、实操篇——远程登录到Linux服务器和远程上传下载文件
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6354397.html
Copyright © 2020-2023  润新知