POJ 2195 Going Home 最小费用流 裸题

给出一个n*m的图,其中m是人,H是房子,.是空地,满足人的个数等于房子数。

现在让每个人都选择一个房子住,每个人只能住一间,每一间只能住一个人。

每个人可以向4个方向移动,每移动一步需要1$,问所有人移动到房子里的最少花费。

其中,n,m<=100,最多有100个人。

最小给用流裸题。

建立一个超级源点,跟每一个房子连一条边,容量为1,花费为0

每一个人与超级汇点连一条边,容量为1,花费为0

一个房子与每一个人建一条边,房子指向人,容量为1,花费用2者的距离(不是直线距离)

然后跑最小费用流算法就可以了。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 #include<queue>
  5 
  6 using namespace std;
  7 
  8 const int maxn=205;
  9 const int inf=0x3f3f3f3f;
 10 const int s=0;
 11 int t;
 12 int tot;
 13 char maze[maxn];
 14 char str[maxn][maxn];
 15 bool vis[maxn];
 16 int dis[maxn];
 17 int prev[maxn];
 18 int pree[maxn];
 19 
 20 struct Point
 21 {
 22     int x,y;
 23 };
 24 Point point[maxn];
 25 struct Edge
 26 {
 27     int to,cap,cost,rev;
 28 };
 29 vector<Edge>edge[maxn];
 30 
 31 inline int get_abs(int tmp)
 32 {
 33     if(tmp>0)
 34         return tmp;
 35     return -tmp;
 36 }
 37 
 38 inline int min(int x,int y)
 39 {
 40     return x<y?x:y;
 41 }
 42 
 43 inline int get_dis(int i,int j)
 44 {
 45     return get_abs(point[i].x-point[j].x)+get_abs(point[i].y-point[j].y);
 46 }
 47 
 48 void addedge(int from,int to,int cap,int cost)
 49 {
 50     edge[from].push_back((Edge){to,cap,cost,edge[to].size()});
 51     edge[to].push_back((Edge){from,0,-cost,edge[from].size()-1});
 52 }
 53 
 54 void build_graph(int n,int m)
 55 {
 56     //要从0开始
 57     for(int i=0;i<maxn;i++)
 58         edge[i].clear();
 59     tot=1;
 60     for(int i=1;i<=n;i++)
 61     {
 62         for(int j=1;j<=m;j++)
 63         {
 64             if(str[i][j]=='H')
 65             {
 66                 point[tot].x=i;
 67                 point[tot++].y=j;
 68             }
 69         }
 70     }
 71     for(int i=1;i<=n;i++)
 72     {
 73         for(int j=1;j<=m;j++)
 74         {
 75             if(str[i][j]=='m')
 76             {
 77                 point[tot].x=i;
 78                 point[tot++].y=j;
 79             }
 80         }
 81     }
 82     t=tot;
 83     tot--;
 84     tot/=2;
 85     for(int i=1;i<=tot;i++)
 86     {
 87         addedge(s,i,1,0);
 88         addedge(i+tot,t,1,0);
 89     }
 90     for(int i=1;i<=tot;i++)
 91     {
 92         for(int j=tot+1;j<=tot*2;j++)
 93         {
 94             addedge(i,j,1,get_dis(i,j));
 95         }
 96     }
 97 }
 98 
 99 void spfa()
100 {
101     memset(vis,false,sizeof vis);
102     for(int i=0;i<=t;i++)
103         dis[i]=inf;
104     queue<int>que;
105     while(!que.empty())
106         que.pop();
107     que.push(s);
108     dis[s]=0;
109     vis[s]=true;
110     while(!que.empty())
111     {
112         int u=que.front();
113         que.pop();
114         vis[u]=false;   //要记得这步
115         for(int i=0;i<edge[u].size();i++)
116         {
117             Edge &e=edge[u][i];
118             if(e.cap>0&&dis[e.to]>dis[u]+e.cost)
119             {
120                 dis[e.to]=dis[u]+e.cost;
121                 prev[e.to]=u;
122                 pree[e.to]=i;
123                 if(!vis[e.to])
124                 {
125                     vis[e.to]=true;
126                     que.push(e.to);
127                 }
128             }
129         }
130     }
131     return ;
132 }
133 
134 int solve()
135 {
136     int ret=0;
137     int flow=tot;
138     while(flow>0)
139     {
140         spfa();
141         int f=flow;
142         for(int i=t;i!=s;i=prev[i])
143         {
144             f=min(f,edge[prev[i]][pree[i]].cap);
145         }
146         flow-=f;
147         ret+=dis[t]*f;
148         for(int i=t;i!=s;i=prev[i])
149         {
150             Edge &e=edge[prev[i]][pree[i]];
151             e.cap-=f;
152             edge[e.to][e.rev].cap+=f;
153         }
154     }
155     return ret;
156 }
157 
158 int main()
159 {
160     int n,m;
161     while(~scanf("%d%d",&n,&m))
162     {
163         if(!n&&!m)
164             break;
165         for(int i=1;i<=n;i++)
166         {
167             scanf("%s",str[i]+1);
168         }
169         build_graph(n,m);
170         printf("%d
",solve());
171     }
172     return 0;
173 }
View Code
原文地址:https://www.cnblogs.com/-maybe/p/4714409.html