Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 17955 | Accepted: 9145 |
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
扫描路径得到人和房子的坐标,相减得所费路程,然后建边最小费用流即可
1 #include<cstdio> 2 #include <queue> 3 #include <algorithm> 4 #include <assert.h> 5 #include <cstring> 6 using namespace std; 7 const int inf=0x7fffffff; 8 int n,m; 9 10 char maz[101][101]; 11 int man[101][2]; 12 int house[101][2]; 13 int hlen,mlen; 14 15 16 const int sups=201; 17 const int supt=202; 18 19 int cost[203][203]; 20 int f[203][203]; 21 int e[203][203]; 22 int len[203]; 23 24 int d[203]; 25 int pre[203]; 26 bool vis[203]; 27 28 queue<int >que; 29 30 int main(){ 31 while(scanf("%d%d",&n,&m)==2&&n&&m){ 32 input: 33 hlen=mlen=0; 34 gets(maz[0]); 35 for(int i=0;i<n;i++){ 36 gets(maz[i]); 37 } 38 for(int i=0;i<n;i++){ 39 for(int j=0;j<m;j++){ 40 if(maz[i][j]==‘m‘){ 41 man[mlen][0]=i;man[mlen++][1]=j; 42 } 43 else if(maz[i][j]==‘H‘){ 44 house[hlen][0]=i;house[hlen++][1]=j; 45 } 46 } 47 } 48 49 memset(f,0,sizeof(f)); 50 memset(cost,0,sizeof(cost)); 51 fill(len,len+mlen,hlen+1);fill(len+mlen,len+mlen+hlen,mlen+1);len[sups]=mlen;len[supt]=hlen; 52 bulidedge: 53 for(int i=0;i<mlen;i++){ 54 f[sups][i]=1; 55 e[sups][i]=i; 56 e[i][0]=sups; 57 for(int j=0;j<hlen;j++){ 58 e[i][j+1]=j+mlen; 59 e[j+mlen][i+1]=i; 60 f[i][j+mlen]=1; 61 cost[i][j+mlen]=abs(man[i][0]-house[j][0])+abs(man[i][1]-house[j][1]); 62 cost[j+mlen][i]=-cost[i][j+mlen]; 63 } 64 } 65 for(int j=0;j<hlen;j++){ 66 e[supt][j]=j+mlen; 67 e[j+mlen][0]=supt; 68 f[j+mlen][supt]=1; 69 } 70 71 mincostflow: 72 int ans=0; 73 int flow=mlen; 74 while(flow>0){ 75 fill(d,d+203,inf); 76 d[sups]=0; 77 que.push(sups); 78 while(!que.empty()){ 79 int fr=que.front();que.pop(); 80 vis[fr]=false; 81 for(int i=0;i<len[fr];i++){ 82 int to=e[fr][i]; 83 if(f[fr][to]>0&&d[to]>d[fr]+cost[fr][to]){ 84 d[to]=d[fr]+cost[fr][to]; 85 pre[to]=fr; 86 if(!vis[to]){ 87 que.push(to); 88 vis[to]=true; 89 } 90 } 91 } 92 } 93 94 assert(d[supt]!=inf); 95 96 int sub=flow; 97 for(int i=supt;i!=sups;i=pre[i]){ 98 sub=min(flow,f[pre[i]][i]); 99 } 100 flow-=sub; 101 ans+=sub*d[supt]; 102 for(int i=supt;i!=sups;i=pre[i]){ 103 f[pre[i]][i]-=sub; 104 f[i][pre[i]]+=sub; 105 } 106 107 } 108 printf("%d\n",ans); 109 } 110 return 0; 111 }
原文:http://www.cnblogs.com/xuesu/p/3924027.html