POJ 2112 Optimal Milking 网络流初步
2016-09-08 20:06
337 查看
POJ 2112 Optimal Milking
网络流初步,二分法
传送门:POJ题意
K个产奶机,C个奶牛,按序标号。每个机子最多处理M个奶牛。给出一个(K+C)*(K+C)的对称矩阵,每个值表示两点距离(不一定是最小距离!)。注意距离是0表示没有路。求走路最多的奶牛走路的路程的最小值。思路
给的不一定是最小值,所以跑一遍Floyd,更新一遍距离数组。网络流建图就是加入源点s,s到每个奶牛连一个容量1的边,奶牛到产奶机距离小于等于mid的话连一条容量为1的边,产奶机到汇点t连一条容量为M的边。
二分判定条件是总流量等于奶牛数目,即所有奶牛都能产奶。
代码
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <cstdlib> #include <stack> using namespace std; const int MAXN=1007; const int oo=0x3f3f3f3f; typedef long long LL; struct Edge{ int from,to,cap,flow;//cap容量 flow流量 Edge(int u,int v,int c,int f){ from=u;to=v;cap=c;flow=f; } }; int m; vector<Edge> edges;//顺序的插入边 vector<int> G[MAXN];//保存边号 int a[MAXN];//起点到i的可改进量 int p[MAXN];//保存当前增广的路径 void init(int n) { for(int i=0;i<n;i++) G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap) { edges.push_back(Edge(from,to,cap,0)); edges.push_back(Edge(to,from,0,0)); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } int Maxflow(int s,int t) { int flow=0; for(;;) { memset(a,0,sizeof(a)); queue<int> Q; Q.push(s); a[s]=oo; while(!Q.empty()) { int x=Q.front();Q.pop(); for(int i=0;i<G[x].size();i++) { Edge& e=edges[G[x][i]]; if(!a[e.to]&&e.cap>e.flow) { p[e.to]=G[x][i]; a[e.to]=min(a[x],e.cap-e.flow); Q.push(e.to); } } if(a[t]) break; } if(!a[t]) break; for(int u=t;u!=s;u=edges[p[u]].from) { edges[p[u]].flow+=a[t]; edges[p[u]^1].flow-=a[t]; } flow+=a[t]; } return flow; } int dis[307][307]; int main() { int k,c,mm; while(scanf("%d%d%d",&k,&c,&mm)==3) { int n=k+c; memset(dis,0,sizeof(dis)); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { int temp; scanf("%d",&(temp)); dis[i][j]=temp==0 ? oo : temp; } } //floyd for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { for(int k=0;k<n;k++) { dis[j][k]=min(dis[j][k],dis[j][i]+dis[i][k]); } } } int l=0,r=100007; while(l<r) { init(n+2); int mid=(l+r)>>1; for(int i=0;i<k;i++) { for(int j=k;j<c+k;j++) { if(dis[i][j]<=mid) { AddEdge(j,i,1); } } } int s_s=++n,s_t=++n; for(int i=0;i<k;i++) { AddEdge(i,s_t,mm); } for(int i=k;i<k+c;i++) { AddEdge(s_s,i,1); } if(Maxflow(s_s,s_t)==c) { r=mid; } else { l=mid+1; } } printf("%d\n",l); } return 0; }
相关文章推荐
- OkHttp的学习(一)
- 神经网络笔记(Neural Network)
- POJ 1273 网络流基础题
- tcping命令详解
- 使用Ajax时处理用户session失效的问题
- OkHttp与Retrofit上传文件详解
- HTTP相关知识 --转载
- HTTP协议:header标头说明
- HttpURLConnection连接服务器失败解决办法
- HTTP和FTP的区别
- Web服务器处理HTTP压缩之gzip、deflate压缩
- JAVA HTTP GET/POST
- 《C#高级编程》读书笔记(十八):网络
- 用c语言写一个网络爬虫
- Http中get和post的区别
- http 报文 - 转
- tcplistener TcpClient UdpClient
- TCPlistener和TCPClient
- OS 64)指定的网络名不再可用 : winnt_accept: Asynchronous AcceptEx failed.
- 关于TCP的socket的bind函数的IP地址参数的详解