您的位置:首页 > 编程语言 > Go语言

POJ 2195 Going Home 费用流 最小费用流

2013-03-27 13:38 423 查看
题目连接:http://poj.org/problem?id=2195

题目大意 :题目的意思就是给你一个map然后m代表人,h代表house,一个人只能进入一个house,一个house只能住一个人,问你所以人进入house所能用的最小步数是多少~

思路:把man和house分别看做一个集合,这样的话你就可以对每个人和每个house 连接,cao = 1,cost = abs(x1-x2)+abs(y1-y2);然后开一个超级源点就可以了。其实模型就是走多少次就是容量。费用根据题目而定。

View Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
const int maxn = 10050;
const int inf = 100000;
char str[105][105];
struct node
{
int x,y;
};
struct edge
{
int u,v,cap,flow,cost;
};
vector<struct node>house;
vector<struct node>man;
vector<int>g[10050];
vector<struct edge>e;
void init(int n)
{
for(int i = 0;i <= n;i++)
g[i].clear();
e.clear();
return;
}
void addedge(int u,int v,int cap,int flow,int cost)
{
e.push_back((struct edge){u,v,cap,flow,cost});
e.push_back((struct edge){v,u,0,flow,-cost});
int m;
m = e.size();
g[u].push_back(m-2);
g[v].push_back(m-1);
return ;
}
int vis[maxn];
int pre[maxn];
int dis[maxn];
int a[maxn];
int spfa(int s,int t,int n,int &flow,int &cost)
{
int i,u,v;
for(i = 0;i <= n;i++)
dis[i] = inf;
memset(vis,0,sizeof(vis));
dis[s] = pre[s] = 0;
a[s] = inf;
queue<int>q;
q.push(s);
vis[s] = 1;
while(!q.empty())
{

u = q.front();
vis[u] = 0;
q.pop();

for(i = 0;i < g[u].size();i++)
{
struct edge & ei = e[g[u][i]];
v = ei.v;
if(ei.cap > ei.flow && dis[v] > dis[u]+ei.cost)
{
dis[v] = dis[u]+ei.cost;
pre[v] = g[u][i];
a[v] = min(a[u],ei.cap-ei.flow);
if(!vis[v])
q.push(v),vis[v] = 1;
}
}
}
if(dis[t] == inf)
return 0;

flow += a[t];
cost += a[t]*dis[t];

u = t;
while(u != s)
{
e[pre[u]].flow += a[t];
e[pre[u]^1].flow -= a[t];
u = e[pre[u]].u;
}
return 1;
}

int mcmf(int s,int t,int n)
{
int flow = 0;
int cost = 0;
while(spfa(s,t,n,flow,cost));
return cost;
}
int main()
{
int m,n,i,j;
while(scanf("%d %d",&n,&m)&&(m||n))
{
for(i = 0;i < n;i++)
scanf("%s",str[i]);
house.clear();
man.clear();
for(i = 0;i < n;i++)
{
for(j = 0;j < m;j++)
{
if(str[i][j] == 'H')
house.push_back((struct node){i,j});
else if(str[i][j] == 'm')
man.push_back((struct node){i,j});
}
}

int hsize,msize;
hsize = house.size();
msize = man.size();

init(hsize+msize+5);
for(i = 0;i < msize;i++)
{
for(j = 0;j < hsize;j++)
{
int cost;
cost = abs(man[i].x-house[j].x)+abs(man[i].y-house[j].y);
addedge(i+1,j+msize+1,1,0,cost);
}
}
for(j = 0;j < man.size();j++)
{
addedge(0,j+1,1,0,0);
}
for(i = 0;i < hsize;i++)
addedge(msize+1+i,msize+hsize+1,1,0,0);

int ans;
ans = 0;
ans = mcmf(0,hsize+msize+1,hsize+msize+2);
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: