标签:路径 while 题解 column mat tween oid vector task
InputThere are one or more test cases in the input. Each case starts with a line giving two integers N and M, where N is the number of rows of the map, and M is the number of columns. The rest of the input will be N lines describing the map. You may assume both N and M are between 2 and 100, inclusive. There will be the same number of ‘H‘s and ‘m‘s on the map; and there will be at most 100 houses. Input will terminate with 0 0 for N and M.
OutputFor each test case, output one line with the single integer, which is the minimum amount, in dollars, you need to pay.
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
题意:使得每个m都对应一个H时的最短的路径
题解:找一个源点,连接所有的m,再找一个汇点,使得所有H指向这个汇点。
然后跑一边最大费用最小流就ok了
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 using namespace std; 9 typedef long long ll; 10 const int MAXX=60010; 11 const int INF=0x3f3f3f3f; 12 13 struct node 14 { 15 int st; 16 int to; 17 int next; 18 int cap; 19 int cost; 20 }edge[MAXX]; 21 22 char mp[102][102]; 23 int head[MAXX],tol; 24 int pre[MAXX],dis[MAXX]; 25 bool vis[MAXX]; 26 int n,m,p; 27 28 struct node1 29 { 30 int x,y; 31 node1(){} 32 node1(int a,int b) 33 { 34 x=a; 35 y=b; 36 } 37 }; 38 vector<node1> v1,v2; 39 40 void init() 41 { 42 tol=0; 43 memset(head,-1,sizeof(head)); 44 v1.clear(); 45 v2.clear(); 46 } 47 48 void addedge(int u,int v,int cap,int cost) 49 { 50 edge[tol].st=u; 51 edge[tol].to=v; 52 edge[tol].cap=cap; 53 edge[tol].cost=cost; 54 edge[tol].next=head[u]; 55 head[u]=tol++; 56 57 edge[tol].st=v; 58 edge[tol].to=u; 59 edge[tol].cap=0; 60 edge[tol].cost=-cost; 61 edge[tol].next=head[v]; 62 head[v]=tol++; 63 } 64 65 bool SPFA(int s,int t) 66 { 67 queue<int> q; 68 memset(dis,INF,sizeof(dis)); 69 memset(vis,0,sizeof(vis)); 70 memset(pre,-1,sizeof(pre)); 71 dis[s]=0; 72 vis[s]=1; 73 q.push(s); 74 while(!q.empty()) 75 { 76 int u=q.front(); q.pop(); 77 vis[u]=0; 78 for(int i=head[u];i!=-1;i=edge[i].next) 79 { 80 int to=edge[i].to; 81 if(edge[i].cap>0&&dis[to]>dis[u]+edge[i].cost) 82 { 83 dis[to]=dis[u]+edge[i].cost; 84 pre[to]=i; 85 if(!vis[to]) 86 { 87 vis[to]=1; 88 q.push(to); 89 } 90 } 91 } 92 } 93 if(pre[t]==-1)return 0; 94 return 1; 95 } 96 97 int minCostMaxFlow(int s,int t) 98 { 99 int cost=0; 100 while(SPFA(s,t)) 101 { 102 int minn=INF; 103 for(int i=pre[t];i!=-1;i=pre[edge[i].st]) 104 minn=min(minn,edge[i].cap); 105 106 for(int i=pre[t];i!=-1;i=pre[edge[i].st]) 107 { 108 edge[i].cap-=minn; 109 edge[i^1].cap+=minn; 110 } 111 cost+=minn*dis[t]; 112 } 113 return cost; 114 } 115 116 int main() 117 { 118 while(scanf("%d%d",&n,&m)&&m&&n) 119 { 120 getchar(); 121 init(); 122 for(int i=0;i<n;i++) 123 { 124 scanf("%s",mp[i]); 125 getchar(); 126 } 127 for(int i=0;i<n;i++) 128 for(int j=0;j<m;j++) 129 { 130 if(mp[i][j]==‘m‘) 131 v1.push_back(node1(i,j)); 132 if(mp[i][j]==‘H‘) 133 v2.push_back(node1(i,j)); 134 135 } 136 int l=v1.size(); 137 int r=v2.size(); 138 for(int i=0;i<v1.size();i++) 139 { 140 141 node1 N1=v1[i]; 142 int x=i+1; 143 addedge(0,x,1,0); 144 for(int j=0;j<v2.size();j++) 145 { 146 node1 N2=v2[j]; 147 int y=j+l+1; 148 int D=abs(N1.x-N2.x)+abs(N1.y-N2.y); 149 addedge(x,y,1,D); 150 addedge(y,x,1,D); 151 if(i==l-1) 152 addedge(y,l+r+1,1,0); 153 } 154 } 155 int ans=minCostMaxFlow(0,l+1+r); 156 printf("%d\n",ans); 157 } 158 return 0; 159 }
Going Home HDU - 1533(最大费用最小流)
标签:路径 while 题解 column mat tween oid vector task
原文地址:https://www.cnblogs.com/Cherry93/p/10029907.html