POJ - 2195 Going Home
2016-10-03 20:25
387 查看
1.题面
http://poj.org/problem?id=21952.题意
最小费用最大流裸题,在一张格点地图上,从一个格子移动到相邻的格子代价为1,每个格子可以站无数个人,求让所有人都走进屋子的最小代价,每个屋子只能待一个人,每个人只能进一个屋子。3.思路
添加一个公共源点,向每个人连一条边,费用为0,容量为1,添加一个公共汇点,由每个屋子往汇点连一条边,费用为0,容量为1.
再从人往屋子连边,费用为人与屋子之间的距离。
再求最小费用流就可以了。
4.代码
/***************************************************************** > File Name: cpp_acm.cpp > Author: Uncle_Sugar > Mail: uncle_sugar@qq.com > Created Time: Mon 03 Oct 2016 19:59:11 CST *****************************************************************/ # include <cstdio> # include <cstring> # include <cctype> # include <cmath> # include <cstdlib> # include <climits> # include <iostream> # include <iomanip> # include <set> # include <map> # include <vector> # include <stack> # include <queue> # include <algorithm> using namespace std; # define rep(i,a,b) for (i=a;i<=b;i++) # define rrep(i,a,b) for (i=b;i>=a;i--) # define mset(aim, val) memset(aim, val, sizeof(aim)) struct QuickIO{ QuickIO(){const int SZ = 1<<20; setvbuf(stdin ,new char[SZ],_IOFBF,SZ); setvbuf(stdout,new char[SZ],_IOFBF,SZ); } //*From programcaicai*// }QIO; template<class T>void PrintArray(T* first,T* last,char delim=' '){ for (;first!=last;first++) cout << *first << (first+1==last?'\n':delim); } /* 1.see the size of the input data before you select your algorithm 2.cin&cout is not recommended in ACM/ICPC 3.pay attention to the size you defined, for instance the size of edge is double the size of vertex */ const int debug = 1; const int size = 10 + 100; const int INF = INT_MAX>>1; typedef long long ll; const int MAXN = 100 + 100*100; const int MAXM = 100000; 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-1 void 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)){ //# cout << "hello" << endl; 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; } typedef pair<int, int> pir; vector<pir> man, house; int dist(const pir& p1, const pir& p2){ return abs(p1.first - p2.first) + abs(p1.second - p2.second); } int main() { /*std::ios::sync_with_stdio(false);cin.tie(0);*/ int n, m; while (~scanf("%d%d", &n, &m)){ if (n==0&&m==0) break; man.clear();house.clear(); char str[size]; for (int i = 0; i < n; i++){ scanf("%s", str); for (int j = 0; j < m; j++){ switch(str[j]){ case 'm':man.push_back(pir(i, j));break; case 'H':house.push_back(pir(i, j));break; } } } int sz = man.size(); init(sz + sz + 2); for (int i = 1; i <= sz; i++){ addedge(0, i, 1, 0); addedge(sz + i, sz + sz + 1, 1, 0); } for (int i = 0; i < sz; i++){ for (int j = 0; j < sz; j++){ addedge(i + 1, sz + j + 1, 1, dist(man[i], house[j])); } } int cost; //# cout << "hello" << endl; int ans = minCostMaxflow(0, sz + sz + 1, cost); printf("%d\n", cost); } return 0; }
相关文章推荐
- POJ 2195 Going Home
- poj 2195 zoj 2404 hdu 1533 Going Home(最小费用流)
- POJ 2195 Going Home(二分图最优匹配)
- zoj 2404 || poj 2195 Going Home
- KM算法 最优匹配(最大权匹配) hdu 2255 奔小康赚大钱 最小权匹配 poj 2195 Going Home
- poj 2195 Going Home (费用流)
- poj2195 going home最小费用流
- poj 2195 Going Home
- POJ 2195 Going Home
- poj 2195//hdu 1533 Going Home 最小费用流(spfa)
- POJ 2195 Going Home 最小费用流 难度:1
- POJ 2195 Going Home(最小费用最大流)
- poj 2195 Going Home
- poj-2195-Going Home最小费用最大流
- POJ训练计划2195_Going Home(网络流/费用流)
- poj2195 Going Home
- POJ 2195 Going Home(KM)- from lanshui_Yang
- poj 2195 Going Home(km)
- poj 2195 Going Home【zkw费用流】
- POJ 2195 Going Home 费用流模版题(附KM算法,转)