HDU1533 最小费用最大流
Going Home
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6478 Accepted Submission(s): 3411
Your task is to compute the minimum amount of money you need to pay in order to send these n little men into those n different houses. The input is a map of the scenario, a '.' means an empty space, an 'H' represents a house on that point, and am 'm' indicates there is a little man on that point.
You can think of each point on the grid map as a quite large square, so it can hold n little men at the same time; also, it is okay if a little man steps on a grid with a house without entering that house.
题意 n个人 n个房子 在N*M个方格 人移动一格要花费 1(只能水平竖直四个方向) 问n个人走到n个房子的最小花费是多少(一个房子只能一个人待)
解析 这道题可以转化成费用流来解决,n个源点n个汇点 最大流为n的最小费用 ,我们直接建立一个超源点0,一个超汇点n*m+1 然后和源点汇点相连 容量1 费用0
注意 其他边的费用为1 但是容量要设为inf 因为走过之后还可以走.
也可以用二分图最大全匹配写 还没get这项技能。。。
代码一 // 一比二快100ms。
- #include<bits/stdc++.h>
- using namespace std;
- const int maxn=1e4+,mod=1e9+,inf=0x3f3f3f3f;
- typedef long long ll;
- #define pb push_back
- #define mp make_pair
- #define X first
- #define Y second
- #define all(a) (a).begin(), (a).end()
- #define fillchar(a, x) memset(a, x, sizeof(a))
- #define huan printf("\n");
- #define debug(a,b) cout<<a<<" "<<b<<" ";
- int dir[][]={{,},{-,},{,-},{,}};
- char a[maxn][maxn];
- struct MCMF {
- struct Edge {
- int from, to, cap, cost;
- Edge(int u, int v, int w, int c): from(u), to(v), cap(w), cost(c) {}
- };
- int n, s, t;
- vector<Edge> edges;
- vector<int> G[maxn];
- int inq[maxn], d[maxn], p[maxn], a[maxn];
- void init(int n) {
- this->n = n;
- for (int i = ; i <= n; i ++) G[i].clear();
- edges.clear();
- }
- void addedge(int from, int to, int cap, int cost) {
- edges.push_back(Edge(from, to, cap, cost));
- edges.push_back(Edge(to, from, , -cost));
- int m = edges.size();
- G[from].push_back(m - );
- G[to].push_back(m - );
- }
- bool BellmanFord(int s, int t, int &flow, int &cost) {
- for (int i = ; i <= n; i ++) d[i] = inf;
- memset(inq, , sizeof(inq));
- d[s] = ; inq[s] = ; p[s] = ; a[s] = inf;
- queue<int> Q;
- Q.push(s);
- while (!Q.empty()) {
- int u = Q.front(); Q.pop();
- inq[u] = ;
- for (int i = ; i < G[u].size(); i ++) {
- Edge &e = edges[G[u][i]];
- if (e.cap && d[e.to] > d[u] + e.cost) {
- d[e.to] = d[u] + e.cost;
- p[e.to] = G[u][i];
- a[e.to] = min(a[u], e.cap);
- if (!inq[e.to]) {
- Q.push(e.to);
- inq[e.to] = ;
- }
- }
- }
- }
- if (d[t] == inf) return false;
- flow += a[t];
- cost += d[t] * a[t];
- int u = t;
- while (u != s) {
- edges[p[u]].cap -= a[t];
- edges[p[u] ^ ].cap += a[t];
- u = edges[p[u]].from;
- }
- return true;
- }
- int solve(int s, int t) {
- int flow = , cost = ;
- while (BellmanFord(s, t, flow, cost));
- return cost;
- }
- }solver;;
- void build(int n,int m)
- {
- vector<int> ss,tt;
- for(int i=;i<=n;i++)
- {
- scanf("%s",a[i]+);
- }
- for(int i=;i<=n;i++)
- {
- for(int j=;j<=m;j++)
- {
- int temp=(i-)*m+j;
- if(a[i][j]=='m')
- ss.push_back(temp);
- else if(a[i][j]=='H')
- tt.push_back(temp);
- for(int k=;k<;k++)
- {
- int x=i+dir[k][];
- int y=j+dir[k][];
- if(x>=&&x<=n&&y>=&&y<=m)
- {
- int temp2=(x-)*m+y;
- solver.addedge(temp,temp2,inf,);
- // cout<<i<<" "<<j<<" "<<temp<<" "<<temp2<<endl;
- }
- }
- }
- }
- for(int i=;i<ss.size();i++)
- solver.addedge(,ss[i],,);
- for(int i=;i<tt.size();i++)
- solver.addedge(tt[i],n*m+,,);
- }
- int main()
- {
- int n,m;
- while(~scanf("%d%d",&n,&m)&&n&&m)
- {
- solver.init(n*m+);
- build(n,m);
- int maxflow;
- maxflow=solver.solve(,n*m+);
- printf("%d\n",maxflow);
- }
- }
代码二
- #include<iostream>
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
- #include<vector>
- #include<queue>
- using namespace std;
- const int maxn=2e4+,mod=1e9+,inf=0x3f3f3f3f;
- struct edge
- {
- int to,next,cap,flow,cost;
- } edge[maxn*];
- int head[maxn],tol;
- int pre[maxn],dis[maxn];
- bool vis[maxn];
- int N;
- char a[maxn][maxn];
- void init(int n)
- {
- N=n,tol=;
- memset(head,-,sizeof(head));
- }
- void addedge(int u,int v,int cap,int cost)
- {
- edge[tol].to=v;
- edge[tol].cap=cap;
- edge[tol].flow=;
- edge[tol].cost=cost;
- edge[tol].next=head[u];
- head[u]=tol++;
- edge[tol].to=u;
- edge[tol].cap=;
- edge[tol].flow=;
- edge[tol].cost=-cost;
- edge[tol].next=head[v];
- head[v]=tol++;
- }
- bool spfa(int s,int t)
- {
- queue<int> q;
- for(int i=; i<=N; i++)
- {
- dis[i]=inf;
- vis[i]=false;
- pre[i]=-;
- }
- dis[s]=;
- vis[s]=true;
- q.push(s);
- while(!q.empty())
- {
- int u=q.front();
- q.pop();
- vis[u]=false;
- for(int i=head[u]; i!=-; 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]==-) return false;
- else return true;
- }
- int mincostflow(int s,int t,int &cost)
- {
- int flow=;
- cost=;
- while(spfa(s,t))
- {
- int Min=inf;
- for(int i=pre[t]; i!=-; i=pre[edge[i^].to])
- {
- if(Min>edge[i].cap-edge[i].flow)
- Min=edge[i].cap-edge[i].flow;
- }
- for(int i=pre[t]; i!=-; i=pre[edge[i^].to])
- {
- edge[i].flow+=Min;
- edge[i^].flow-=Min;
- cost+=edge[i].cost*Min;
- }
- flow+=Min;
- }
- return flow;
- }
- int dir[][]={{,},{-,},{,-},{,}};
- void build(int n,int m)
- {
- vector<int> ss,tt;
- for(int i=;i<=n;i++)
- {
- scanf("%s",a[i]+);
- }
- for(int i=;i<=n;i++)
- {
- for(int j=;j<=m;j++)
- {
- int temp=(i-)*m+j;
- if(a[i][j]=='m')
- ss.push_back(temp);
- else if(a[i][j]=='H')
- tt.push_back(temp);
- for(int k=;k<;k++)
- {
- int x=i+dir[k][];
- int y=j+dir[k][];
- if(x>=&&x<=n&&y>=&&y<=m)
- {
- int temp2=(x-)*m+y;
- addedge(temp,temp2,inf,);
- // cout<<i<<" "<<j<<" "<<temp<<" "<<temp2<<endl;
- }
- }
- }
- }
- for(int i=;i<ss.size();i++)
- addedge(,ss[i],,);
- for(int i=;i<tt.size();i++)
- addedge(tt[i],n*m+,,);
- }
- int main()
- {
- int n,m;
- while(~scanf("%d%d",&n,&m)&&n&&m)
- {
- init(n*m+);
- build(n,m);
- int ans,maxflow;
- maxflow=mincostflow(,n*m+,ans);
- printf("%d\n",ans);
- }
- }
HDU1533 最小费用最大流的更多相关文章
- hdu1533 Going Home 最小费用最大流 构造源点和汇点
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- [hdu1533]二分图最大权匹配 || 最小费用最大流
题意:给一个n*m的地图,'m'表示人,'H'表示房子,求所有人都回到房子所走的距离之和的最小值(距离为曼哈顿距离). 思路:比较明显的二分图最大权匹配模型,将每个人向房子连一条边,边权为曼哈顿距离的 ...
- [板子]最小费用最大流(Dijkstra增广)
最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...
- bzoj1927最小费用最大流
其实本来打算做最小费用最大流的题目前先来点模板题的,,,结果看到这道题二话不说(之前打太多了)敲了一个dinic,快写完了发现不对 我当时就这表情→ =_=你TM逗我 刚要删突然感觉dinic的模 ...
- ACM/ICPC 之 卡卡的矩阵旅行-最小费用最大流(可做模板)(POJ3422)
将每个点拆分成原点A与伪点B,A->B有两条单向路(邻接表实现时需要建立一条反向的空边,并保证环路费用和为0),一条残留容量为1,费用为本身的负值(便于计算最短路),另一条残留容量+∞,费用为0 ...
- HDU5900 QSC and Master(区间DP + 最小费用最大流)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...
- P3381 【模板】最小费用最大流
P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行 ...
- 【BZOJ-3876】支线剧情 有上下界的网络流(有下界有源有汇最小费用最大流)
3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 821 Solved: 502[Submit][Status ...
- hdu 4411 2012杭州赛区网络赛 最小费用最大流 ***
题意: 有 n+1 个城市编号 0..n,有 m 条无向边,在 0 城市有个警察总部,最多可以派出 k 个逮捕队伍,在1..n 每个城市有一个犯罪团伙, 每个逮捕队伍在每个城市可以选 ...
随机推荐
- 最优雅退出 Android 应用程序的 6 种方式
一.容器式 建立一个全局容器,把所有的Activity存储起来,退出时循环遍历finish所有Activity import java.util.ArrayList; import java.util ...
- Angular JS中变量定义的基本原则
在Angular JS开发中,经常需要定义一些变量,关于这些变量的定义方法及作用域应该注意以下几点: 1. 如果能用局部变量解决问题,尽量不要用全局变量. 2. 需要与界面双向绑定的变量采用$scop ...
- monkeyrunner 简单用例编写
monkeyrunnerfrom com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImagedevice = Monke ...
- 51nod 1432 独木舟
基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 n个人,已知每个人体重.独木舟承重固定,每只独木舟最多坐两个人,可以坐一个人或者两个人.显然要求总重量不超过独木舟承 ...
- 千万千万不要运行的 Linux 命令
文中列出的命令绝对不可以运行,即使你觉得很好奇也不行,除非你是在虚拟机上运行(出现问题你可以还原),因为它们会实实在在的破坏你的系统.所以不在root等高级管理权限下执行命令是很好的习惯. 早晚有一天 ...
- org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'needDao' defined in URL
这个是我修改过后的mapper,是我的mapper中的空间地址写错了呢
- 关于dzzoffice 破解版
最近看到很多人在搜索dzzoffice破解版,其实dzzoffie是一款全开源的产品,开放的功能是与演示站中一摸一样的,所以并不会有人破解这种全开源的系统.那么为什么会有人搜索这样的关键词呢? 可能大 ...
- Linux php安装zip扩展
Linux php安装zip扩展 2018.07.22 22:40 1165浏览 #wget http://pecl.php.net/get/zip-1.12.4.tgz #tar zxfv zi ...
- DROP FUNCTION - 删除一个函数
SYNOPSIS DROP FUNCTION name ( [ type [, ...] ] ) [ CASCADE | RESTRICT ] DESCRIPTION 描述 DROP FUNCTION ...
- chrome 打开上次关闭的tab ctrl+shift+T
chrome 打开上次关闭的tab ctrl+shift+T