zoukankan      html  css  js  c++  java
  • bzoj1070[SCOI2007]修车

    传送门

    最小费用最大流,又是一道思维题,我又没想出建图,问题想对了,就是不会解决,建图大概就是对于每个工人每个时间段建个点,只要想到将(n)个工人分成((n*m))个点,剩下的就简单了,zkw费用流在这题表现不佳

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    inline void read(int &x) {
        char ch; bool ok;
        for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
        for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define min(a,b) (a<b?a:b)
    #define rg register
    int n,m,s,t,sla[100001],pre[100001],dis[100001],nxt[100001],h[50001],v[100001],w[100001],cnt=1,inf=1e9,ans;bool vis[100001];
    void add(int x,int y,int z,int u)
    {
        pre[++cnt]=y,nxt[cnt]=h[x],h[x]=cnt,v[cnt]=z,w[cnt]=u,
        pre[++cnt]=x,nxt[cnt]=h[y],h[y]=cnt,v[cnt]=0,w[cnt]=-u;
    }
    int dfs(int x,int flow)
    {
        if(x==t){ans+=dis[t]*flow;return flow;}
        vis[x]=1;int f=flow;
        for(rg int i=h[x];i;i=nxt[i])
            if(!vis[pre[i]]&&v[i])
            {
                if(!(dis[x]+w[i]-dis[pre[i]]))
                {
                    int y=dfs(pre[i],min(v[i],f));
                    f-=y,v[i]-=y,v[i^1]+=y;
                    if(!f)return flow;
                }
                else sla[pre[i]]=min(sla[pre[i]],dis[x]+w[i]-dis[pre[i]]);
            }
        return flow-f;
    }
    int aug()
    {
        int mn=inf;
        for(rg int i=s;i<=t;i++)if(!vis[i])mn=min(mn,sla[i]),sla[i]=inf;
        if(mn==inf)return 1;
        for(rg int i=s;i<=t;i++)if(!vis[i])dis[i]+=mn;
        return 0;
    }
    int main()
    {
        read(n),read(m),s=0,t=(n+2)*m+1;
        for(rg int i=1,x;i<=m;i++)
            for(rg int j=1;j<=n;j++)
            {
                read(x);
                for(rg int k=1;k<=m;k++)add(i,j*m+k,1,k*x);
            }
        for(rg int i=1;i<=m;i++)add(s,i,1,0);
        for(rg int i=1;i<=m;i++)for(rg int j=1;j<=n;j++)add(j*m+i,t,1,0);
        memset(sla,63,sizeof sla);
        while(1)
        {
            while(1){memset(vis,0,sizeof vis);if(!dfs(s,inf))break;}
            if(aug())break;
        }
        printf("%.2lf
    ",1.0*ans/m);
    }
    
  • 相关阅读:
    Poj 2017 Speed Limit(水题)
    Poj 1316 Self Numbers(水题)
    Poj 1017 Packets(贪心策略)
    Poj 1017 Packets(贪心策略)
    Poj 2662,2909 Goldbach's Conjecture (素数判定)
    Poj 2662,2909 Goldbach's Conjecture (素数判定)
    poj 2388 Who's in the Middle(快速排序求中位数)
    poj 2388 Who's in the Middle(快速排序求中位数)
    poj 2000 Gold Coins(水题)
    poj 2000 Gold Coins(水题)
  • 原文地址:https://www.cnblogs.com/lcxer/p/10223472.html
Copyright © 2011-2022 走看看