hdu1533(最小费用最大流spfa模板)

来源:互联网 发布:gta5ol捏脸美女数据 编辑:程序博客网 时间:2024/05/21 00:46

题意:

n个人,进n个房子,每走一格花费1元,每个房子只能进一人,求所有人进房子的最小花费。

思路:

建立网络图,设置大源点和大汇点。跑mcmf;

代码:

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 400;const int maxm = 200000;const int inf = 0x3f3f3f3f;int dis[maxn];int vis[maxn],pre[maxn];int head[maxn],cnt;int n,m;struct node{    int to,cap,cost,next;}edge[maxm];void add(int from,int to,int cap,int cost){    edge[cnt].to = to;    edge[cnt].cap = cap;    edge[cnt].cost = cost;    edge[cnt].next = head[from];    head[from] = cnt++;    edge[cnt].to = from;    edge[cnt].cap = 0;    edge[cnt].cost = -cost;    edge[cnt].next = head[to];    head[to] = cnt++;}bool spfa(int s,int t,int &flow,int &cost){    queue<int> q;    memset(dis,inf,sizeof(dis));    memset(vis,0,sizeof(vis));    memset(pre,-1,sizeof(pre));    dis[s] = 0;    q.push(s);    vis[s] = 1;    int d = inf;    while(!q.empty())    {        int u = q.front();        q.pop();        vis[u] = 0;        for(int i = head[u];i!=-1;i=edge[i].next)        {            int v = edge[i].to;            if(edge[i].cap>0&&dis[v]>dis[u]+edge[i].cost)            {                dis[v] = dis[u]+edge[i].cost;                pre[v] = i;                if(!vis[v])                {                    vis[v] = 1;                    q.push(v);                }            }        }    }    if(dis[t]==inf)    {        return false;    }    for(int i = pre[t];i!=-1;i = pre[edge[i^1].to])    {        d = min(d,edge[i].cap);    }    for(int i = pre[t];i!=-1;i = pre[edge[i^1].to])    {        edge[i].cap -= d;        edge[i^1].cap += d;        cost+=edge[i].cost*d;    }    flow += d;    return true;}int mcmf(int s,int t){    int flow = 0,cost = 0;    while(spfa(s,t,flow,cost))    {        //cout<<flow<<" "<<cost<<endl;    }    return cost;}struct Home{    int x,y;}H[maxn],P[maxn];int totH,totP;void input(){    char c;    totH=0;totP=0;    for(int i=1;i<=n;i++)   {       for(int j=1;j<=m;j++)    {        scanf("%c",&c);        if(c=='H') totH++,H[totH].x=i,H[totH].y=j;            else if(c=='m') totP++,P[totP].x=i,P[totP].y=j;    }      getchar();   }}int main(){    while(~scanf("%d%d",&n,&m)&&n&&m)    {        memset(head,-1,sizeof(head));        cnt=0;        getchar();        input();        for(int i = 1;i<=totP;i++)        {            for(int j = 1;j<=totH;j++)            {                int t=abs(P[i].x-H[j].x)+abs(P[i].y-H[j].y);                add(i,j+totP,1,t);            }        }        for(int i = 1;i<=totP;i++)        {            add(totP+totH+1,i,1,0);        }        for(int i = totP+1;i<=totH+totP;i++)        {            add(i,totH+totP+2,1,0);        }        printf("%d\n",mcmf(totH+totP+1,totH+totP+2));    }    return 0;}

原创粉丝点击