[kuangbin带你飞]专题十一 网络流 D POJ – 2195

来源:互联网 发布:图像空间的消隐算法 编辑:程序博客网 时间:2024/05/29 19:19

题目地址:https://vjudge.net/contest/68128#problem/D
思路:最小费用最大流模板题
AC代码:

#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<cmath>#include<cstdlib>using namespace std;const int MAXN = 300+10;const int MAXM = 1e5+10;const int INF = 0x3f3f3f3f;char g[MAXN][MAXN];struct edge{    int u,v,next,cap,flow,cost;}edge[MAXM];int tol;struct pos{    int x,y;};pos h[MAXN];pos m[MAXN];int head[MAXN];int n,M;int getdis(int j,int i){    return abs(h[i].x-m[j].x)+abs(h[i].y-m[j].y);}void addedge(int u,int v,int cap,int cost){    edge[tol].u=u;    edge[tol].v=v;    edge[tol].cap=cap;    edge[tol].flow=0;    edge[tol].cost=cost;    edge[tol].next=head[u];    head[u]=tol++;    edge[tol].u=v;    edge[tol].v=u;    edge[tol].cap=0;    edge[tol].flow=0;    edge[tol].cost=-cost;    edge[tol].next=head[v];    head[v]=tol++;}bool in[MAXN];int dis[MAXN];int pre[MAXN];int flow;int cost;bool spfa(int s,int t){    memset(in,false,sizeof(in));    memset(dis,INF,sizeof(dis));    memset(pre,-1,sizeof(pre));    queue<int>q;    q.push(s);    dis[s]=0;    in[s]=true;    while(!q.empty()){        int u=q.front();        q.pop();        in[u]=false;        for(int i=head[u];i!=-1;i=edge[i].next){            int v=edge[i].v;            //cout<<"v:"<<v<<endl;            if(edge[i].cap>edge[i].flow && dis[v]>dis[u]+edge[i].cost){                dis[v]=dis[u]+edge[i].cost;                pre[v]=i;                if(!in[v]){                    q.push(v);                    in[v]=true;                }            }        }    }    if(dis[t]==INF)        return false;    return true;}void solve(int s,int t){    while(spfa(s,t)){        int minn=INF;        for(int i=pre[t];i!=-1;i=pre[edge[i^1].v]){            minn=min(edge[i].cap-edge[i].flow,minn);        }        for(int i=pre[t];i!=-1;i=pre[edge[i^1].v]){            edge[i].flow+=minn;            edge[i^1].flow-=minn;            cost +=edge[i].cost*minn;        }        flow+=minn;       // cout<<cost<<endl;    }}int main(){    while(scanf("%d%d",&n,&M)){        tol=0;    memset(head,-1,sizeof(head));        if(n==0 && M==0)            break;        int hh=1,mm=1;        flow=0,cost=0;        for(int i=0;i<n;i++){            scanf("%s",g[i]);            for(int j=0;j<M;j++){                if(g[i][j]=='H'){                    h[hh].x=i;                    h[hh++].y=j;                }                if(g[i][j]=='m'){                    m[mm].x=i;                    m[mm++].y=j;                }            }        }        mm--,hh--;        for(int i=1;i<=mm;i++){            addedge(0,i,1,0);        }        for(int i=1;i<=mm;i++)        for(int j=1;j<=hh;j++){            int temp=getdis(i,j);           // cout<<i<<" "<<j+mm<<endl;            addedge(i,j+mm,1,temp);        }        for(int i=mm+1;i<=mm+hh;i++){            addedge(i,hh+mm+1,1,0);        }        solve(0,hh+mm+1);        cout<<cost<<endl;    }}
0 0
原创粉丝点击