Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 17777 | Accepted: 9059 |
Description
Input
Output
Sample Input
2 2 .m H. 5 5 HH..m ..... ..... ..... mm..H 7 8 ...H.... ...H.... ...H.... mmmHmmmm ...H.... ...H.... ...H.... 0 0
Sample Output
2 10 28
Source
题目大意:
解题思路:m表示人,H表示房子,它们之间的距离是曼哈顿距离,问你所有人一人个房子的总花费是多少?
解题代码:用最小费用流即可。构图略。
#include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int maxn=11000; const int maxm=1100000; const int inf=(1<<30); struct edge{ int u,v,next,f,c; edge(int u0=0,int v0=0,int f0=0,int c0=0,int next0=0){ u=u0,v=v0,f=f0,c=c0,next=next0; } }e[maxm]; int head[maxn],path[maxn],dist[maxn]; bool visited[maxn]; int cnt,src,sink; void init(){ cnt=0; memset(head,-1,sizeof(head)); } void adde(int u,int v,int f,int c){ e[cnt].u=u,e[cnt].v=v,e[cnt].f=f,e[cnt].c=c,e[cnt].next=head[u],head[u]=cnt++; e[cnt].u=v,e[cnt].v=u,e[cnt].f=0,e[cnt].c=-c,e[cnt].next=head[v],head[v]=cnt++; } bool bfs(){ for(int i=src;i<=sink;i++){ dist[i]=inf; path[i]=-1; } dist[src]=0; queue <int> q; q.push(src); visited[src]=true; while(!q.empty()){ int s=q.front(); q.pop(); for(int i=head[s];i!=-1;i=e[i].next){ int d=e[i].v; if(e[i].f>0 && dist[s]+e[i].c<dist[d]){ dist[d]=dist[s]+e[i].c; path[d]=i; if(!visited[d]){ visited[d]=true; q.push(d); } } } visited[s]=false; } return path[sink]>=0; } int getMinCost(){ int ret=0; while(bfs()){ int delta=inf; for(int i=sink;i!=src;i=e[path[i]].u){ if( e[path[i]].f<delta ) delta=e[path[i]].f; } for(int i=sink;i!=src;i=e[path[i]].u){ e[path[i]].f-=delta; e[path[i]^1].f+=delta; } ret+=dist[sink]*delta; } return ret; } int n,m; void input(){ init(); src=0; char a[110]; vector < pair<int,int> > house,man; for(int i=0;i<n;i++){ scanf("%s",&a); for(int j=0;j<m;j++){ if(a[j]=='H') house.push_back(make_pair(i,j)); else if(a[j]=='m') man.push_back(make_pair(i,j)); } } sink=house.size()+man.size()+1; for(int i=1;i<=man.size();i++) adde(src,i,1,0); for(int i=1;i<=man.size();i++){ for(int j=1;j<=house.size();j++){ int tdis=abs(man[i-1].first-house[j-1].first)+abs(man[i-1].second-house[j-1].second); adde(i,j+man.size(),1,tdis); } } for(int i=1;i<=house.size();i++) adde(i+man.size(),sink,1,0); } void solve(){ printf("%d\n",getMinCost()); } int main(){ while(scanf("%d%d",&n,&m)!=EOF && (m||n) ){ input(); solve(); } return 0; }
POJ 2195 Going Home(网络流-费用流),布布扣,bubuko.com
原文:http://blog.csdn.net/a1061747415/article/details/38402111