zoukankan      html  css  js  c++  java
  • BZOJ4349 最小树形图

    据说是一道重题 可以见[JSOI2008]小店购物

    同样是最小树形图 可以注意到每个点只要都被打了一次那么接下来都可以使用最小的代价来攻打

    那么我们把第一次进行的攻打跑最小树形图即可 注意要建虚点作为起始状态

    【最开始想错了 以为必须全打掉才可以用后来的新代价 WA飞以后看题解才明白qaq

    //Love and Freedom.
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define inf 1e20
    #define ll long long
    #define N 1100
    #define M 100100
    #define db double
    using namespace std;
    
    struct edge{int u,v; db c;}e[M];
    int pre[N],id[N],vis[N];
    int n,m;db mn[N];
    db zlal(int rt)
    {
        db res = 0.0;
        while(1)
        {
            for(int i=1;i<=n;i++)    mn[i] = inf;
            for(int i=1;i<=m;i++)
                if(e[i].u != e[i].v && mn[e[i].v]>e[i].c)
                {
                    mn[e[i].v] = e[i].c; pre[e[i].v] = e[i].u;
                }
            for(int i=1;i<=n;i++)    if(i!=rt && mn[i]==inf)    return 0;
            int tn = 0,u,v;
            memset(id,0,sizeof(id)); memset(vis,0,sizeof(vis));
            mn[rt] = 0;
            for(int i=1;i<=n;i++)
            {
                res += mn[i]; v=i;
                while(v!=rt && !id[v] && vis[v]!=i)
                    vis[v] = i, v = pre[v];
                if(v!=rt && !id[v])
                {
                    ++tn;
                    for(u=pre[v];u!=v;u=pre[u])
                        id[u] = tn;
                    id[v] = tn;
                }
            }
            if(!tn)    break;
            for(int i=1;i<=n;i++)    if(!id[i])
                id[i] = ++tn;
            for(int i=1;i<=m;i++)
            {
                v = e[i].v;
                e[i].u = id[e[i].u];
                e[i].v = id[e[i].v];
                if(e[i].u != e[i].v)
                    e[i].c -= mn[v];
            }
            n = tn; rt = id[rt];
        }
        return res;
    }
    db a[N],cc[N]; int b[N],cnt;
    int main()
    {
        //int r;    scanf("%d%d%d",&n,&m,&r);
        //for(int i=1;i<=m;i++)    scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].c);
        scanf("%d",&n); n++; db ans = 0.0;
        for(int i=1;i<n;i++)
        {
            scanf("%lf%d",&a[i],&b[i]);
            if(b[i]<=0)    continue;// ans+=(b[i]-1)*a[i];
            e[++cnt].u = n, e[cnt].v=i ,cc[i]=e[cnt].c=a[i];
        }
        int k,x,y;db c; scanf("%d",&k);
        for(int i=1;i<=k;i++)
        {
            scanf("%d%d%lf",&x,&y,&c);
            e[++cnt].u=x; e[cnt].v=y; e[cnt].c=c; cc[y]=min(cc[y],c);
        } m = cnt;
        for(int i=1;i<n;i++)    ans+=(b[i]-1)*cc[i];
        printf("%.2lf
    ",zlal(n) +ans);
        return 0;
    }
    /**
    3 
    10.00 1
    1.80 1 
    2.50 2
    2
    1 3 2.00
    3 2 1.50
    */
    View Code
  • 相关阅读:
    浅谈三层模式
    javascript的全局变量
    BZOJ 3668 NOI2014 起床困难综合症 贪心
    调试经验--图像
    Mac OS X 10.10 执行 Eclipse 提示须要安装 Java
    ubuntuOS
    BLOB存储图片文件二进制数据是非对错
    API经济产业
    python模块目录文件后续
    MongoDB命令
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/10366717.html
Copyright © 2011-2022 走看看