[kuangbin带你飞]专题十一 网络流 D POJ – 2195
2017-04-21 16:38
447 查看
题目地址:https://vjudge.net/contest/68128#problem/D
思路:最小费用最大流模板题
AC代码:
思路:最小费用最大流模板题
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; } }
相关文章推荐
- [kuangbin带你飞]专题十一 网络流 A POJ - 3436
- [kuangbin带你飞]专题十一 网络流 B POJ - 3281
- [kuangbin带你飞]专题十一 网络流
- [kuangbin带你飞]专题十一 网络流
- kuangbin专题十一网络流总结
- POJ 3087 Shuffle'm Up(kuangbin带你飞 专题一:简单搜索)专题一完结
- [kuangbin带你飞]专题一 简单搜索E - Find The Multiple(POJ 1426)
- [kuangbin带你飞]专题一 简单搜索 K - 迷宫问题 POJ 3984
- [kuangbin带你飞]专题四 最短路练习 H POJ 3660
- [kuangbin带你飞]专题四 最短路练习 M POJ 1062
- [kuangbin带你飞]专题六 最小生成树 D POJ 2421
- [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher H POJ 2752
- [kuangbin带你飞]专题1 简单搜索 E - Find The Multiple POJ - 1426
- [kuangbin带你飞]专题九 连通图 E - Redundant Paths POJ - 3177
- POJ - 3087 模拟 [kuangbin带你飞]专题一
- POJ 3126 Prime Path(kuangbin带你飞 专题一:简单搜索)
- POJ 3279 Fliptile(kuangbin带你飞 专题一:简单搜索)
- POJ 1751 Highways(kuangbin带你飞 专题六:最小生成树)
- [kuangbin带你飞]专题1 简单搜索 K - 迷宫问题 POJ - 3984
- [kuangbin带你飞]专题一 简单搜索F - Prime Path(POJ 3126)