Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 24600 | Accepted: 12327 |
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
Pacific Northwest 2004
最小费用最大流的模板题。
建图:源点——>m点——>H点——>汇点。
源点——>m点流量为1,费用为0;
所有m点和所有H点连一条边,流量为1,费用为abs(m.x-H.x)+abs(m.y-H.y);
H点——>汇点流量为1,费用为0。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int INF=0x3f3f3f3f;
struct Edge{
int from,to,cap,flow,cost,next;
}edge[50005];
int head[50005],pre[50005],dist[50005],edgenum=0;
bool vis[50005];
void init(){
edgenum=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w,int c){
Edge E1={u,v,w,0,c,head[u]};
edge[edgenum]=E1;
head[u]=edgenum++;
Edge E2={v,u,0,0,-c,head[v]};
edge[edgenum]=E2;
head[v]=edgenum++;
}
bool spfa(int s,int t){
queue q;
while (q.size()) q.pop();
memset(dist,INF,sizeof(dist));
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
dist[s]=0;
vis[s]=1;
q.push(s);
while (q.size()){
int u=q.front();
q.pop();
vis[u]=0;
for (int i=head[u];i!=-1;i=edge[i].next){
Edge E=edge[i];
if (dist[E.to]>dist[u]+E.cost && E.cap>E.flow){
dist[E.to]=dist[u]+E.cost;
pre[E.to]=i;
if (!vis[E.to]){
vis[E.to]=1;
q.push(E.to);
}
}
}
}
return pre[t]!=-1;
}
void mcmf(int s,int t,int &cost,int &flow){
flow=0;
cost=0;
while(spfa(s,t)){
int Min=INF;
for (int i=pre[t];i!=-1;i=pre[edge[i^1].to]){
Edge E=edge[i];
Min=min(Min,E.cap-E.flow);
}
for (int i=pre[t];i!=-1;i=pre[edge[i^1].to]){
edge[i].flow+=Min;
edge[i^1].flow-=Min;
cost+=edge[i].cost*Min;
}
flow+=Min;
}
}
struct P{
int x,y;
P(){}
P(int a,int b):x(a),y(b){}
};
int Distance(P a,P b){
return abs(a.x-b.x)+abs(a.y-b.y);
}
int main(){
int n,m;
while (cin>>n>>m && (n||m)){
init();
vector q1;
vector
q2;
int s=0;
int t=500;
int cost,flow;
for (int i=0;i>str;
for (int j=0;j