zoukankan      html  css  js  c++  java
  • POJ2455 Secret Milking Machine 二分+最大流

      题目链接:http://poj.org/problem?id=2455

      题意有点绕,简而言之就是要你找出T条每条边都边不重复的路径,使得的这T条路径中的每段路径的最大值最小,求出这个最大值。首先找出T条边不重复的路径,可以想到用增光路来搞,把每条边的权值赋值为1,那整个网络的最大流就是边不重复的路径的数目了,因为每条边的流量为1,最多只能在一条增广路上,所以最终由多少个可行流就有多少条边不重复的路径,就是最大流了。那么这样就可以比较快的求出来。然后发现,给图的边加个限制,即权值小于等于limit的为可行边,那么T和limit是个线性关系,就可以二分来搞了。然后要注意这个题目的数据有平行边,我因为开始没有注意,WA到死啊!血的教训!

      1 //STATUS:G++_AC_282MS_2432KB
      2 #include<stdio.h>
      3 #include<stdlib.h>
      4 #include<string.h>
      5 #include<math.h>
      6 #include<iostream>
      7 #include<string>
      8 #include<algorithm>
      9 #include<vector>
     10 #include<queue>
     11 #include<stack>
     12 #include<map>
     13 using namespace std;
     14 #define LL long long
     15 #define Max(a,b) ((a)>(b)?(a):(b))
     16 #define Min(a,b) ((a)<(b)?(a):(b))
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define lson l,mid,rt<<1
     19 #define rson mid+1,r,rt<<1|1
     20 const int MAX=210,INF=0x3f3f3f3f;
     21 
     22 struct Edge{
     23     int u,v,c;
     24 }e[MAX*MAX*2];
     25 
     26 struct List{
     27     int a,b,len;
     28 }l[MAX*MAX];
     29 
     30 int d[MAX],cur[MAX];
     31 int first[MAX],next[MAX*MAX*2];
     32 int n,m,k,maxlen,minlen,mm;
     33 
     34 void addedge(int u,int v)
     35 {
     36     e[mm].u=u;e[mm].v=v;
     37     e[mm].c=1;
     38     next[mm]=first[u],first[u]=mm++;
     39     e[mm].u=v;e[mm].v=u;
     40     e[mm].c=1;
     41     next[mm]=first[v],first[v]=mm++;
     42 }
     43 
     44 int bfs(int s,int t)
     45 {
     46     int x,i;
     47     queue<int> q;
     48     mem(d,0);
     49     d[s]=1;
     50     q.push(s);
     51     while(!q.empty()){
     52         x=q.front();q.pop();
     53         for(i=first[x];i!=-1;i=next[i]){
     54             if(e[i].c>0 && !d[e[i].v]){
     55                 d[e[i].v]=d[x]+1;
     56                 q.push(e[i].v);
     57             }
     58         }
     59     }
     60     return d[t];
     61 }
     62 
     63 int dfs(int x,int a)
     64 {
     65     if(x==n || a==0)return a;
     66     int t,f,flow=0;
     67     for(int& i=cur[x];i!=-1;i=next[i]){
     68         if(d[x]+1==d[e[i].v] && (f=dfs(e[i].v,Min(a,e[i].c)))>0){
     69             e[i].c-=f;
     70             e[i^1].c+=f;
     71             flow+=f;
     72             a-=f;
     73             if(!a)break;
     74         }
     75     }
     76     return flow;
     77 }
     78 
     79 int dinic(int s,int t,int limit)
     80 {
     81     int i,ret=0;
     82     while(bfs(s,t)){
     83         for(i=1;i<=n;i++)cur[i]=first[i];
     84         ret+=dfs(s,INF);
     85     }
     86     return ret;
     87 }
     88 
     89 int binary()
     90 {
     91     int i,t,low=minlen,mid,high=maxlen;
     92     while(low<high){
     93         mid=(low+high)>>1;
     94         mem(first,-1);
     95         for(i=mm=0;i<m;i++)
     96             if(l[i].len<=mid)
     97                 addedge(l[i].a,l[i].b);
     98         t=dinic(1,n,mid);
     99         if(t<k)low=mid+1;
    100         else high=mid;
    101     }
    102     return low;
    103 }
    104 
    105 int main()
    106 {
    107  //   freopen("in.txt","r",stdin);
    108     int i;
    109     while(~scanf("%d%d%d",&n,&m,&k))
    110     {
    111         maxlen=-INF;minlen=INF;
    112         for(i=0;i<m;i++){
    113             scanf("%d%d%d",&l[i].a,&l[i].b,&l[i].len);
    114             if(l[i].len>maxlen)maxlen=l[i].len;
    115             if(l[i].len<minlen)minlen=l[i].len;
    116         }
    117 
    118         printf("%d\n",binary());
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    Spring一些常用注解及其作用
    Spring、Springboot、Springcloud的区别
    JVM常见配置
    Statement对象
    运算符优先级
    Java中的关键字有哪些?
    Servlet生命周期
    String类型的认识以及编译器优化
    JSTL--简单标签
    JSTL--表达式操作
  • 原文地址:https://www.cnblogs.com/zhsl/p/2795593.html
Copyright © 2011-2022 走看看