ZKW优化费用流

Posted very_czy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZKW优化费用流相关的知识,希望对你有一定的参考价值。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
double pi=acos(-1.0);
double eps=1e-8;
const int mod=1e9+7;
bool vis[200001];
int dist[200001];
int n,m,s,t,ans=0;
int nedge=-1,p[200001],c[200001],cc[200001],nex[200001],head[200001];
inline void addedge(int x,int y,int z,int zz)
{
    p[++nedge]=y;
    c[nedge]=z;
    cc[nedge]=zz;
    nex[nedge]=head[x];
    head[x]=nedge;
}
inline bool spfa(int s,int t)
{
    memset(vis,0,sizeof vis);
    for(int i=0; i<=n; i++)dist[i]=1e9;
    dist[t]=0;
    vis[t]=1;
    deque<int>q;
    q.push_back(t);
    while(!q.empty())
    {
        int now=q.front();
        q.pop_front();
        for(int k=head[now]; k>-1; k=nex[k])if(c[k^1]&&dist[p[k]]>dist[now]-cc[k])
            {
                dist[p[k]]=dist[now]-cc[k];
                if(!vis[p[k]])
                {
                    vis[p[k]]=1;
                    if(!q.empty()&&dist[p[k]]<dist[q.front()])q.push_front(p[k]);
                    else q.push_back(p[k]);
                }
            }
        vis[now]=0;
    }
    return dist[s]<1e9;
}
inline int dfs(int x,int low)
{
    if(x==t)
    {
        vis[t]=1;
        return low;
    }
    int used=0,a;
    vis[x]=1;
    for(int k=head[x]; k>-1; k=nex[k])if(!vis[p[k]]&&c[k]&&dist[x]-cc[k]==dist[p[k]])
        {
            a=dfs(p[k],min(c[k],low-used));
            if(a)ans+=a*cc[k],c[k]-=a,c[k^1]+=a,used+=a;
            if(used==low)break;
        }
    return used;
}
inline int costflow()
{
    int flow=0;
    while(spfa(s,t))
    {
        vis[t]=1;
        while(vis[t])
        {
            memset(vis,0,sizeof vis);
            flow+=dfs(s,1e9);
        }
    }
    return flow;
}
map<string,int>mp;
int cnt=0;
int main()
{
    int T;
    scanf ("%d",&T);
    while (T--)
    {
        cnt=0;
        mp.clear();
        memset(nex,-1,sizeof nex);
        memset(head,-1,sizeof head);
        nedge=-1;
        ans=0;
        scanf("%d",&m);
        char s1[20],s2[20];
        int val;
        for(int i=1; i<=m; i++)
        {
            scanf ("%s%s%d",s1,s2,&val);
            int x,y;
            if (mp[s1]==0)
            {
                cnt+=2;
                x=mp[s1]=cnt;
                addedge(x,x-1,1,0);
                addedge(x-1,x,0,0);

                addedge(x-1,x,1,0);
                addedge(x,x-1,0,0);
            }
            else x=mp[s1];
            if (mp[s2]==0)
            {
                cnt+=2;
                y=mp[s2]=cnt;
                addedge(y,y-1,1,0);
                addedge(y-1,y,0,0);

                addedge(y-1,y,1,0);
                addedge(y,y-1,0,0);
            }
            else y=mp[s2];

            addedge(x,y-1,1,val);
            addedge(y-1,x,0,-val);

            addedge(y,x-1,1,val);
            addedge(x-1,y,0,-val);
        }
        if (mp["Dalian"]==0||mp["Xian"]==0||mp["Shanghai"]==0)
        {
            printf ("-1\n");
            continue;
        }
        n=cnt+2;
        s=++cnt;
        t=++cnt;

        addedge(s,mp["Shanghai"],2,0);
        addedge(mp["Shanghai"],s,0,0);
        addedge(mp["Dalian"],t,1,0);
        addedge(t,mp["Dalian"],0,0);
        addedge(mp["Xian"],t,1,0);
        addedge(t,mp["Xian"],0,0);

        if (costflow()==2)
        printf("%d\n",ans);
        else printf ("-1\n");
    }
    return 0;
}

  

以上是关于ZKW优化费用流的主要内容,如果未能解决你的问题,请参考以下文章

zkw费用流模板

ZKW费用流

[转]从入门到精通: 最小费用流的“zkw算法”

餐巾计划问题 网络流24题费用流zkw

P2053 [SCOI2007]修车zkw费用流

网络流——最小费用最大流模板