POJ 2455 Secret Milking Machine 【二分】+【最大流】
<题目链接>
题目大意:
FJ有N块地,这些地之间有P条双向路,每条路的都有固定的长度l。现在要你找出从第1块地到第n块地的T条不同路径,每条路径上的路段不能与先前的路径重复,问这些路径中的最长路段的最小值是多少。
解题分析:
最小的最大值问题,依然需要用二分答案,枚举出该最大路段的长度,然后将所有小于等于这个值得路段加入网络,将这些路段的容量置为1。因为是无向图,所以正、反向弧的容量都置为1,之后跑一遍最大流,再根据最大流和T的大小关系来判断。
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 using namespace std; 6 7 #define INF 0x3f3f3f3f 8 #define mem(a,b) memset(a,b,sizeof(a)) 9 const int N=210; 10 11 struct Edge{ 12 int u,v,c; 13 }edge[N*N*2]; 14 15 struct Segment{ 16 int a,b,len; 17 }seg[N*N]; 18 19 int d[N],cur[N]; 20 int head[N],next[N*N*2]; 21 int n,m,k,maxlen,minlen,cnt; 22 23 void addedge(int u,int v,int w){ 24 edge[cnt].u=u;edge[cnt].v=v,edge[cnt].c=w; 25 next[cnt]=head[u],head[u]=cnt++; 26 27 edge[cnt].u=v;edge[cnt].v=u,edge[cnt].c=w; 28 next[cnt]=head[v],head[v]=cnt++; 29 } 30 31 int bfs(int s,int t){ 32 queue<int> q; 33 mem(d,0); 34 d[s]=1; 35 q.push(s); 36 while(!q.empty()){ 37 int x=q.front();q.pop(); 38 for(int i=head[x];i!=-1;i=next[i]){ 39 if(edge[i].c>0 && !d[edge[i].v]){ 40 d[edge[i].v]=d[x]+1; 41 q.push(edge[i].v); 42 } 43 } 44 } 45 return d[t]; 46 } 47 48 int dfs(int x,int a){ 49 if(x==n || a==0)return a; 50 int t,f,flow=0; 51 for(int& i=cur[x];i!=-1;i=next[i]){ 52 if(d[x]+1==d[edge[i].v] && (f=dfs(edge[i].v,min(a,edge[i].c)))>0){ 53 edge[i].c-=f; 54 edge[i^1].c+=f; 55 flow+=f; 56 a-=f; 57 if(!a)break; 58 } 59 } 60 return flow; 61 } 62 63 int dinic(int s,int t,int limit){ 64 int i,ret=0; 65 while(bfs(s,t)){ 66 for(i=1;i<=n;i++)cur[i]=head[i]; 67 ret+=dfs(s,INF); 68 } 69 return ret; 70 } 71 72 int binary_solve(){ 73 int low=minlen,high=maxlen; 74 while(low<high){ //这个二分答案部分对格式还是有点疑惑 75 int mid=(low+high)>>1; 76 cnt=0;mem(head,-1); //init() 77 for(int i=0;i<m;i++) //加入所有满足要求的边 78 if(seg[i].len<=mid) 79 addedge(seg[i].a,seg[i].b,1); 80 int t=dinic(1,n,mid); 81 if(t<k)low=mid+1; 82 else high=mid; 83 } 84 return low; 85 } 86 87 int main(){ 88 while(~scanf("%d%d%d",&n,&m,&k)){ 89 maxlen=-INF;minlen=INF; 90 for(int i=0;i<m;i++){ 91 scanf("%d%d%d",&seg[i].a,&seg[i].b,&seg[i].len); 92 maxlen=max(maxlen,seg[i].len); 93 minlen=min(minlen,seg[i].len); 94 } 95 printf("%d\n",binary_solve()); 96 } 97 return 0; 98 }
2018-11-24
作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。