hdu 1533 Going Home (最小费用最大流)
来源:互联网 发布:剑网三萝莉脸型数据图 编辑:程序博客网 时间:2024/03/28 23:05
/*题意:给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致。man每移动一格需花费$1(即单位费用=单位距离),一间house只能入住一个man。现在要求所有的man都入住house,求最小费用。 把man作为一个顶点集合U,house作为另一个顶点集合V,把U中所有点到V中所有点连线, 费用cost[u][v]为abs(△x)+abs(△y),反向弧费用cost[v][u]= -cost[u][v], 容量cap[u][v]=1,构成一个多源多汇的二分图。 由于每一个多源多汇的网络流都必有一个与之对应的单源单汇的网络流, 为了便于解题,由此构造一个超级源s和超级汇t,超级源s与U中所有点相连, 费用cost[s][u]=0(这是显然的) 容量cap[s][u]=1;V中所有点与超级汇t相连,费用cost[v][t]=0(这是显然的),容量cap[t][v]=1。*/# include <stdio.h># include <algorithm># include <stack># include <queue># include <string.h>using namespace std;# define MAXM 500010//边# define MAXN 10010//点# define INF 0x3fffffstruct node{ int x; int y;};node cotm[5010],coth[5010];struct Edge{ int to,next,cap,flow,cost;} edge[MAXM];int head[MAXN],tol;int pre[MAXN],dis[MAXN];bool vis[MAXN];int N;//节点总个数,节点编号从0~N-1void init(int n){ N = n; tol = 0; memset(head,-1,sizeof (head));}void addedge (int u,int v,int cap,int cost){ edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++;}bool spfa(int s,int t){ queue<int>q; for(int i = 0; i < N; i++) { dis[i] = INF; vis[i] = false; pre[i] = -1; } dis[s] = 0; vis[s] = true; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = false; for(int i = head[u]; i != -1; i = edge[i]. next) { int v = edge[i]. to; 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(!vis[v]) { vis[v] = true; q.push(v); } } } } if(pre[t] == -1)return false; else return true;}//返回的是最大流,cost存的是最小费用int minCostMaxflow(int s,int t,int &cost){ int flow = 0; cost = 0; while(spfa(s,t)) { int Min = INF; for(int i = pre[t]; i != -1; i = pre[edge[i^1].to]) { if(Min > edge[i].cap - edge[i]. flow) Min = edge[i].cap - edge[i].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; } return flow;}int main(){ int n,m,cot1,cot2,i,j; char a[110][110]; while(~scanf("%d%d",&n,&m),n+m) { cot1=0; cot2=0; for(i=0; i<n; i++) scanf("%s",a[i]); for(i=0; i<n; i++) { for(j=0; j<m; j++) { if(a[i][j]=='m') { cot1++; cotm[cot1].x=i+1; cotm[cot1].y=j+1; } else if(a[i][j]=='H') { cot2++; coth[cot2].x=i+1; coth[cot2].y=j+1; } } } // printf("%d %d\n",cot1,cot2); int sa=0;//超级源点 int ed=cot1+cot2+1;//超级汇点 init(ed+1);//总节点数 for(i=1; i<=cot1; i++) addedge(sa,i,1,0); for(i=1; i<=cot2; i++) addedge(i+cot1,ed,1,0); for(i=1; i<=cot1; i++) { for(j=1; j<=cot2; j++) { int x=abs(cotm[i].x-coth[j].x)+abs(cotm[i].y-coth[j].y); addedge(i,j+cot1,1,x); } } int cost; int aa=minCostMaxflow(sa,ed,cost); printf("%d\n",cost); } return 0;}
0 0
- hdu 1533 Going Home【最大流最小费用流】
- hdu 1533 || poj 2195 Going Home (最小费用最大流)
- hdu 1533 going home (最小费用最大流)
- POJ 2195 & HDU 1533 Going Home(最小费用最大流)
- hdu 1533 Going Home 最小费用最大流 入门题
- HDU 1533 Going Home(最小费用最大流模版)
- HDU 1533 — Going Home 最小费用最大流
- hdu 1533 Going Home(最小费用最大流)
- hdu 1533 Going Home (最小费用最大流)
- HDU 1533 Going Home 最小费用最大流
- HDU 1533--Going Home【最小费用最大流 && 模板】
- hdu 1533 Going Home(最小费用最大流)
- hdu 1533 Going Home 最小费用流
- HDU 1533 Going Home 最小费用流
- Going Home (hdu 1533 最小费用流)
- HDU 1533 Going Home(最小费用流)
- hdu 1533 Going Home (最小费用流)
- Going Home hdu 1533 最小费用最大流,费用流好用模板
- C++ 中在进程中的窗口句柄传入线程
- java.lang.NoClassDefFoundError: org/objectweb/asm/Type
- leetcode-20-Valid Parentheses
- Android之——AIDL小结
- hiho1192 简单的树嵌入(构造题)
- hdu 1533 Going Home (最小费用最大流)
- 杨辉三角_java_HDU2032
- 内存管理
- SSL/TLS双向认证实现(JAVA、TOMCAT)
- Fine-Grained Histopathological Image Analysis via Robust Segmentation and Large-Scale Retrieval文章总结
- 分离各位数
- 找数达人
- UIImage类目-返回一张拉伸的图片、自动设配6 7
- Linux内核驱动之自动创建设备文件