码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-10-18 23:41:05      阅读:401      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   ar   for   sp   

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

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

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

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

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

bubuko.com,布布扣
  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 }
View Code

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

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

标签:style   blog   http   color   io   os   ar   for   sp   

原文地址:http://www.cnblogs.com/zhyfzy/p/4033824.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!