【网络流#2】hdu 1533 最小费用最大流模板题

嗯~第一次写费用流题。。。

这道就是费用流的模板题,找不到更裸的题了

建图:每个m(Man)作为源点,每个H(House)作为汇点,各个源点与汇点分别连一条边,这条边的流量是1(因为每个源点只能走一条边到汇点),费用是 从源点走到汇点的步数,因为有多个源点与汇点,要建一个超级源点与超级汇点,超级源点与各个源点连一条流量为1,费用为0(要避免产生多余的费用)的边

按照这个图跑一发费用流即可

把代码挂上去,用的是前向星写的

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<set>
  7 #include<map>
  8 #include<stack>
  9 #include<vector>
 10 #include<queue>
 11 #include<string>
 12 #include<sstream>
 13 #define MAXN 3000
 14 #define MAXM 50000
 15 #define INF (1<<30)
 16 #define eps 0.000001
 17 #define ALL(x) x.begin(),x.end()
 18 #define INS(x) inserter(x,x.begin())
 19 using namespace std;
 20 int i,j,k,n,m,x,y,T,num,w,Man,House,hou[305][2],man[305][2];
 21 int head[MAXN],vis[MAXN],dis[MAXN],pos[MAXN],Edge,size;
 22 char s[305][305];
 23 struct edgenode
 24 {
 25     int to,next,w,cost;
 26 } edge[MAXM];
 27
 28 void add_edge(int x,int y,int w,int cost)
 29 {
 30     edge[Edge].to=y;
 31     edge[Edge].w=w;
 32     edge[Edge].cost=cost;
 33     edge[Edge].next=head[x];
 34     head[x]=Edge;
 35     Edge++;
 36
 37
 38     edge[Edge].to=x;
 39     edge[Edge].w=0;
 40     edge[Edge].cost=-cost;
 41     edge[Edge].next=head[y];
 42     head[y]=Edge;
 43     Edge++;
 44 }
 45
 46 bool SPFA(int s, int t)
 47 {
 48     int u,v,i;
 49     queue <int> q;
 50     memset(vis,0,sizeof(vis));
 51     for(i=0;i<size;i++) dis[i]=INF;
 52      dis[s]=0;
 53      vis[s]=1;
 54     q.push(s);
 55     while(!q.empty())
 56     {
 57         u=q.front(); q.pop(); vis[u]=0;
 58         for (i=head[u];i!=-1;i=edge[i].next)
 59           {
 60                v=edge[i].to;
 61                if(edge[i].w>0&&dis[u]+edge[i].cost<dis[v])
 62                {
 63                 dis[v]=dis[u]+edge[i].cost;
 64                 pos[v]=i;
 65                 if(!vis[v])
 66                 {
 67                      vis[v]=1;
 68                      q.push(v);
 69                 }
 70                }
 71           }
 72     }
 73     return dis[t]!=INF;
 74 }
 75 int MinCostFlow(int s,int t)
 76 {
 77     int i,cost=0,flow=0;
 78     while(SPFA(s,t))
 79     {
 80         int d=INF;
 81         for (i=t;i!=s;i=edge[pos[i]^1].to)
 82         {
 83             d=min(d,edge[pos[i]].w);
 84         }
 85         for(i=t;i!=s;i=edge[pos[i]^1].to)
 86         {
 87             edge[pos[i]].w-=d;
 88             edge[pos[i]^1].w+=d;
 89         }
 90         flow+=d;
 91         cost+=dis[t]*d;
 92     }
 93     return cost; // flow是最大流值
 94 }
 95
 96 int main()
 97 {
 98     while(scanf("%d%d",&n,&m),n+m)
 99     {
100         memset(head,-1,sizeof(head));
101         Edge=Man=House=num=0;
102         for (i=0;i<n;i++) scanf("%s",s[i]);
103         for (i=0;i<n;i++)
104         {
105             for (j=0;j<m;j++)
106             {
107                 if (s[i][j]==‘m‘)
108                 {
109                     Man++;
110                     man[Man][0]=i;
111                     man[Man][1]=j;
112                 }else
113                 if (s[i][j]==‘H‘)
114                 {
115                     House++;
116                     hou[House][0]=i;
117                     hou[House][1]=j;
118                 }
119             }
120         }
121         size=Man+House+2;
122         /*超级源点0,到各个人的边*/
123         for (i=1;i<=Man;i++)
124         {
125             add_edge(0,i,1,0);
126         }
127         /*各源点与各汇点之间的边*/
128         for (i=1;i<=Man;i++)
129         {
130             for (j=1;j<=House;j++)
131             {
132                 add_edge(i,Man+j,1,abs(man[i][0]-hou[j][0])+abs(man[i][1]-hou[j][1]));
133             }
134         }
135         /*超级汇点0,到各个人的边*/
136         for (i=1;i<=House;i++)
137         {
138             add_edge(Man+i,Man+House+1,1,0);
139         }
140         printf("%d\n",MinCostFlow(0,Man+House+1));
141     }
142     return 0;
143 }

据说可以用KM算法来写,下次补上KM算法的代码。。。

时间: 2024-09-29 10:20:38

【网络流#2】hdu 1533 最小费用最大流模板题的相关文章

hdu 1533(最小费用最大流)

Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4223    Accepted Submission(s): 2178 Problem Description On a grid map there are n little men and n houses. In each unit time, every l

POJ2135 最小费用最大流模板题

练练最小费用最大流 此外此题也是一经典图论题 题意:找出两条从s到t的不同的路径,距离最短. 要注意:这里是无向边,要变成两条有向边 #include <cstdio> #include <cstring> #define MAXN 1005 #define MAXM 10005 #define INF 0x3f3f3f3f struct Edge { int y,c,w,ne;//c容量 w费用 }e[MAXM*4]; int n,m,x,y,w; int s,t,Maxflow

HDU 1533 最小费用最大流(模板)

http://acm.hdu.edu.cn/showproblem.php?pid=1533 这道题直接用了模板 题意:要构建一个二分图,家对应人,连线的权值就是最短距离,求最小费用 要注意void init(int n) 这个函数一定要写 一开始忘记写这个WA了好几发 还有这个题很容易T掉,赋值建图要简化,一开始构建成网络流那种图一直T #include <stdio.h> #include <string.h> #include <iostream> #includ

hdu 2516 最小费用最大流

原来这个代码超时 #include<stdio.h> #include<queue> #include<string.h> using namespace std; #define N 200 #define inf 0x3fffffff int cap[N][N]; int fee[N][N]; int s,t,sum,pre[N]; int spfa() { queue<int>q; int dis[N],visit[N],u,i; memset(pre

poj 2135 Farm Tour (最小费用最大流模板)

网络流的费用: 在实际应用中,与网络流有关的问题,不仅涉及流量,而且还有费用的因素.网络的每一条边(v,w)除了给定容量cap(v,w)外,还定义了一个单位流量费用cost(v,w) 最小费用最大流问题 给定网络G,要求G的一个最大用流flow,使流的总费用最小. 求解MCMF问题的算法: 最小费用最大流最常用和基本的算法我们可以称它为最小费用路算法,其思想与求最大流的增广路算法类似,不断在残流网络中寻找从源s到汇t的最小费用路,即残流网络中从s到t的以费用为权的最短路,然后沿最小费用路增流,直

POJ2135Farm Tour(最小费用最大流模板)

题目链接:http://poj.org/problem?id=2135 题意:农场主想从1到n,然后从n到1,每条边最多走一次,不能走重复的路,问最短距离是多少. 建图:取超级源点s,并与房子连一条边,容量为2,费用为0:取barn与超级汇点 t 的边的容量为2,费用为0 房子与barn的费用为距离,容量为1 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring>

hdu 1533 Going Home 最小费用最大流 入门题

Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3125    Accepted Submission(s): 1590 Problem Description On a grid map there are n little men and n houses. In each unit time, every

HDU 1533--Going Home【最小费用最大流 &amp;&amp; 模板】

Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3452    Accepted Submission(s): 1771 Problem Description On a grid map there are n little men and n houses. In each unit time, every

多校第一场:HDU 4862 最小费用最大流

思路:这题主要是建图搞了好久,以前没判断过满流,所以又看了这个知识点,然后才发现自己的最小费用最大流在求满流的时候有bug,正好改了过来. 建图:开始看题解知道这题是最小费用最大流,然后没看解释就做了.然后自己建的图没得求出答案,然后想了好久也没发现哪里错.然后看了官方题解,发现自己的建图和官方差太大了.可能是受昨天做POJ最小费用建图的影响吧.官方的建太符合题目意思了,只能说,我还看了好久建图才理解的. 构造二部图,X部有N*M个节点,源点向X部每个节点连一条边,流量1,费用0:Y部有N*M个