poj-2112-Optimal Milking(最大流)
2016-05-06 16:25
441 查看
传送门
题意:K个产奶机,C头奶牛,每个产奶机最多可供M头奶牛使用;并告诉了产奶机、奶牛之间的两两距离Dij(0<=i,j < K+c)。
问题:如何安排使得在任何一头奶牛都有自己产奶机的条件下,奶牛到产奶机的最远距离最短?最短是多少?
Dinic算法
先floyd求得两两之间最小距离,然后二分寻找答案
邻接链表的方法
邻接矩阵做法,比邻接表略慢
题意:K个产奶机,C头奶牛,每个产奶机最多可供M头奶牛使用;并告诉了产奶机、奶牛之间的两两距离Dij(0<=i,j < K+c)。
问题:如何安排使得在任何一头奶牛都有自己产奶机的条件下,奶牛到产奶机的最远距离最短?最短是多少?
Dinic算法
先floyd求得两两之间最小距离,然后二分寻找答案
邻接链表的方法
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define N 250 const int INF = 0x3f3f3f3f; using namespace std; struct node{ int to, cap, next; }edge[N*N]; int K, c, m, a , st, en, n, cnt; int first , level , q ; int cap ; void read(int u, int v, int c){ edge[cnt].cap = c; edge[cnt].next = first[u]; edge[cnt].to = v; first[u] = cnt++; edge[cnt].cap = 0; edge[cnt].next = first[v]; edge[cnt].to = u; first[v] = cnt++; } void init(int dis){ cnt = 0; memset(first, -1, sizeof(first)); n = K+c; st = 0; en = n+1; for (int i = 1; i <= K; i++){ read(0, i, m); } for (int i = K+1; i <= n; i++){ read(i, en, 1); } for (int i = 1; i <= K; i++){ for (int j = K+1; j <= n; j++){ if (a[i][j] <= dis){ read(i, j, 1); } } } } bool bfs(int s, int t){ memset(level, 0, sizeof(level)); level[s] = 1; int rear = 0, front = 0; q[front++] = s; while(rear < front){ int x = q[rear++]; if (x == t) return true; for (int e = first[x]; e != -1; e = edge[e].next){ int v = edge[e].to; int f = edge[e].cap; if (!level[v] && f){ level[v] = level[x]+1; q[front++] = v; } } } return false; } int dfs(int u, int maxf, int t){ if (u == t) return maxf; int ret = 0; for (int e = first[u]; e != -1; e = edge[e].next){ int v = edge[e].to; int f = edge[e].cap; if (level[u]+1 == level[v] && f){ int Min = min(maxf-ret, f); f = dfs(v, Min, t); edge[e].cap -= f; edge[e^1].cap += f; ret += f; if (ret == maxf) return ret; } } return ret; } int dinic(int s, int t){ int ans = 0; while(bfs(s, t)) ans += dfs(s, INF, t); return ans; } int main(){ #ifndef ONLINE_JUDGE freopen("1.txt", "r", stdin); #endif int i, j, k; while(~scanf("%d%d%d", &K, &c, &m)){ for (i = 1; i <= K+c; i++){ for (j = 1; j <= K+c; j++){ scanf("%d", &a[i][j]); if(a[i][j] == 0) a[i][j] = INF; } } for (k = 1; k <= K+c; k++){ for (i = 1; i <= K+c; i++){ for (j = 1; j <= K+c; j++){ a[i][j] = min(a[i][j], a[i][k]+a[k][j]); } } } int ans = 1, low = 1, high = INF; while(low <= high){ int mid = (low+high)>>1; init(mid); if (dinic(st, en) == c){ ans = mid; high = mid-1; }else{ low = mid+1; } } printf("%d\n", ans); } return 0; }
邻接矩阵做法,比邻接表略慢
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define N 250 const int INF = 0x3f3f3f3f; using namespace std; int K, c, m, a , st, en, n; int first , level , q ; int cap ; void Init(int dis){ memset(cap, 0, sizeof(cap)); n = K+c; st = 0; en = n+1; for (int i = 1; i <= K; i++){ cap[0][i] = m; } for (int i = K+1; i <= n; i++){ cap[i][en] = 1; } for (int i = 1; i <= K; i++){ for (int j = K+1; j <= n; j++){ if (a[i][j] <= dis) cap[i][j] = 1; } } } bool bfs(int s, int t){ memset(level, 0, sizeof(level)); level[st] = 1; int rear = 0, front = 0; q[front++] = st; while(rear < front){ int v = q[rear++]; if (v == en) return true; for (int i = 0; i <= K+c+1; i++){ if (!level[i] && cap[v][i]){ level[i] = level[v] + 1; q[front++] = i; } } } return false; } int dfs(int u, int maxf, int t){ if (u == t) return maxf; int ret = 0, f; for (int i = 1; i <= K+c+1; i++){ if (level[u] + 1 == level[i] && cap[u][i]){ f = dfs(i, min(cap[u][i], maxf-ret), t); cap[u][i] -= f; cap[i][u] += f; ret += f; if (ret == maxf) return ret; } } return ret; } int dinic(int s, int t){ int ans = 0; while(bfs(s, t)) ans += dfs(s, INF, t); return ans; } int main(){ #ifndef ONLINE_JUDGE freopen("1.txt", "r", stdin); #endif int i, j, k; while(~scanf("%d%d%d", &K, &c, &m)){ for (i = 1; i <= K+c; i++){ for (j = 1; j <= K+c; j++){ scanf("%d", &a[i][j]); if(a[i][j] == 0) a[i][j] = INF; } } for (k = 1; k <= K+c; k++){ for (i = 1; i <= K+c; i++){ for (j = 1; j <= K+c; j++){ a[i][j] = min(a[i][j], a[i][k]+a[k][j]); } } } int ans = 1, low = 1, high = INF; while(low <= high){ int mid = (low+high)>>1; Init(mid); if (dinic(st, en) == c){ ans = mid; high = mid-1; }else{ low = mid+1; } } printf("%d\n", ans); } return 0; }
相关文章推荐
- STL---heap概述,make_heap,sort_heap,pop_heap,push_heap
- Windows 08R2 IIS网站架设
- opencv3.0.0 and ubuntu15.10:CMake Error at 3rdparty/ippicv/downloader.cmake:75
- web Toast pop 弹窗 效果 悬置2s 消失
- 如何设计和维护好一个大项目
- 【Shell】一些比较有用、常用的shell命令
- django 获取系统当前时间 和linux 系统当前时间不一致 问题处理。
- OpenFileDialog获取文件名和文件路径问题
- linux vim 替换指定字符为回车
- 正确地复制对象--oeprator=与copy构造函数
- LAM P编译安装
- Linux:各种锁
- windows上搭建hadoop开发环境
- win10家庭版安装Linux双系统
- apache commons io checkstyle报告(2016-04-21更新)
- linux 系统资源限制查看
- nginx入门
- LINUX 命令使用技巧
- 我的linux学习决心书
- 9、利用JavaScript在网站显示时间