POJ-2195-Going Home

来源:互联网 发布:template.js 编辑:程序博客网 时间:2024/06/05 06:16

比较裸地最小费用流题,对每个人对每个房子进行连容量为1的边,然后设定源点,并向所有的人连费用为0,容量为1的边,然后设定汇点,房子向汇点连容量为1费用为0的边。然后跑最小费用流

代码:

#include<cstdio>#include<cstring>#include<iostream>#include<queue>#include<cmath>using namespace std;const int inf=1<<29;const int maxn=1e4+100;const int maxm=2e5;struct Node{    int x;    int y;    Node(){}    Node(int sx,int sy)    {        x=sx;        y=sy;    }}P[maxn],H[110];int e,st,des,head[maxn],nxt[maxm],cost[maxm],flow[maxm],pnt[maxm],dist[maxn],pre[maxn];int n,m,a[110][110],ho_id,pep_id;bool vis[maxn];queue<int> q;char map[110][110];void AddEdge(int u,int v,int c,int f){    pnt[e]=v;nxt[e]=head[u];cost[e]=c;flow[e]=f;head[u]=e++;    pnt[e]=u;nxt[e]=head[v];cost[e]=-c;flow[e]=0;head[v]=e++;}bool Spfa(int st,int des){    for(int i=st;i<=des;i++)    {        dist[i]=inf;        pre[i]=-1;    }    dist[st]=0;    q.push(st);    while(!q.empty())    {        int u=q.front();        vis[u]=0;        q.pop();        for(int i=head[u];i!=-1;i=nxt[i])            if(flow[i]&&dist[pnt[i]]>dist[u]+cost[i])            {                dist[pnt[i]]=dist[u]+cost[i];                pre[pnt[i]]=i;                if(!vis[pnt[i]])                {                    vis[pnt[i]]=1;                    q.push(pnt[i]);                }            }    }    return dist[des]!=inf;}int mincostflow(){    int ans=0;    while(Spfa(st,des))    {        int mini=inf;        for(int i=pre[des];i!=-1;i=pre[pnt[i^1]])            mini=min(mini,flow[i]);        for(int i=pre[des];i!=-1;i=pre[pnt[i^1]])        {            flow[i]-=mini;            flow[i^1]+=mini;        }        ans+=mini*dist[des];    }    return ans;}void Build(){    e=st=0;des=pep_id+ho_id+1;    memset(head,-1,sizeof(head));    for(int i=0;i<pep_id;i++)    {        AddEdge(st,i+1,0,1);        for(int j=0;j<ho_id;j++)            AddEdge(i+1,pep_id+1+j,abs(P[i].x-H[j].x)+abs(P[i].y-H[j].y),1);    }    for(int i=0;i<ho_id;i++)        AddEdge(pep_id+i+1,des,0,1);}void solve(){    Build();    printf("%d\n",mincostflow());}int main(){    while(scanf("%d%d",&n,&m)&&(n+m))    {        ho_id=pep_id=0;        memset(a,0,sizeof(a));        for(int i=0;i<n;i++)            scanf("%s",map[i]);        for(int i=0;i<n;i++)            for(int j=0;j<m;j++)            {                if(map[i][j]=='m')                    P[pep_id++]=Node(i,j);                if(map[i][j]=='H')                    H[ho_id++]=Node(i,j);            }        solve();    }    return 0;}


0 0