费用流 poj2195 Going Home
2015-08-16 00:25
519 查看
传送门:点击打开链接
费用流裸题,,感觉不是因为我模板慢,,应该是因为vector的原因。。
题意:每个人都要回已房子,费用是哈曼顿距离,每个房子只能容纳1人,问最小费用
超级源点连接每一个人,每个人再连很多条边对应房子
再把每个房子连接超级汇点
模板一套,,就做完了
费用流裸题,,感觉不是因为我模板慢,,应该是因为vector的原因。。
题意:每个人都要回已房子,费用是哈曼顿距离,每个房子只能容纳1人,问最小费用
超级源点连接每一个人,每个人再连很多条边对应房子
再把每个房子连接超级汇点
模板一套,,就做完了
#include<map> #include<set> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<string> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; typedef long long LL; typedef pair<int, int> PII; const int MX = 80000 + 5;//都开4倍把.. const int MM = 80000 + 5; const int INF = 0x3f3f3f3f; struct Edge { int to, next, cap, flow, cost; Edge() {} Edge(int _to, int _next, int _cap, int _flow, int _cost) { to = _to; next = _next; cap = _cap; flow = _flow; cost = _cost; } } E[MM]; int Head[MX], tol; int pre[MX]; //储存前驱顶点 int dis[MX]; //储存到源点s的距离 bool vis[MX]; int N;//节点总个数,节点编号从0~N-1 void init(int n) { tol = 0; N = 2 * n + 2; memset(Head, -1, sizeof(Head)); } void addedge(int u, int v, int cap, int cost) { E[tol] = Edge(v, Head[u], cap, 0, cost); Head[u] = tol++; E[tol] = Edge(u, Head[v], 0, 0, -cost); 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 = E[i].next) { int v = E[i].to; if (E[i].cap > E[i].flow && dis[v] > dis[u] + E[i].cost) { dis[v] = dis[u] + E[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)) { int Min = INF; for (int i = pre[t]; i != -1; i = pre[E[i ^ 1].to]) { if (Min > E[i].cap - E[i].flow) Min = E[i].cap - E[i].flow; } for (int i = pre[t]; i != -1; i = pre[E[i ^ 1].to]) { E[i].flow += Min; E[i ^ 1].flow -= Min; cost += E[i].cost * Min; } flow += Min; } return flow; } int m, n; char S[1000]; vector<PII>Beg, End; int dist(PII a, PII b) { return abs(a.first - b.first) + abs(a.second - b.second); } int main() { //freopen("input.txt", "r", stdin); while(~scanf("%d%d", &m, &n), m + n) { Beg.clear(); End.clear(); for(int i = 0; i < m; i++) { scanf("%s", S); for(int j = 0; j < n; j++) { if(S[j] == 'm') Beg.push_back(PII(i, j)); if(S[j] == 'H') End.push_back(PII(i, j)); } } init(Beg.size() + End.size()); int s = 0, t = 2 * (Beg.size() + End.size()) + 1; for(int i = 0; i < Beg.size(); i++) { addedge(s, i + 1, 1, 0); } for(int i = 0; i < End.size(); i++) { addedge(i + Beg.size() + 1, t, 1, 0); } for(int i = 0; i < Beg.size(); i++) { for(int j = 0; j < End.size(); j++) { addedge(i + 1, Beg.size() + j + 1, 1, dist(Beg[i], End[j])); } } int ans = 0; minCostMaxflow(s, t, ans); printf("%d\n", ans); } return 0; }
相关文章推荐
- Codeforces Gym 100203G G - Good elements 标记暴力
- UVa 11292 - Dragon of Loowater
- Codeforces Gym 100203G G - Good elements 暴力
- Codeforces Gym 100203G Good elements 暴力乱搞
- MetaStudio和DataScraper链接失败及登陆问题的解决(GooSeeker产品)
- STL algorithm中的swap 函数使用
- Django基础学习<2>
- hdu 3635 Dragon Balls
- HDU 5289 Assignment (二分+RMQ)
- go read text file into string array
- Django基础学习<1>
- HDU 2255 奔小康赚大钱 POJ 2195 Going Home 最大权完美匹配 KM算法
- Go 函数
- django-rest-framework指南(1):序列化
- Google编码规范
- Go语言入门
- Heagon的程序流程(二)
- Django(上)
- [转] Google工程师教你编写垃圾回收器
- POJ 2262 Goldbach's Conjecture(素数筛选法)