您的位置:首页 > 理论基础 > 计算机网络

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

2017-04-21 16:38 447 查看
题目地址: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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: