• poj2112 二分+floyd+多源多汇最大流


    /*此题不错,大致题意:c头牛去k个机器处喝奶,每个喝奶处最多容纳M头牛,求所有牛中走的最长路的
    那头牛,使该最长路最小。思路:最大最小问题,第一灵感:二分答案check之。对于使最长路最短,
    用folyd算出所有牛到每个喝奶点的最短路,每次枚举最大值,取不大于该值的路,重新构图;把所有牛赶去
    喝奶点,在喝奶点有限制,不是多源多汇吗?!取超级源点,限制为1(一头牛),超级汇点,限制为
    m,即可。其他路限制随意。
    关键点:分清哪些是流量,最短路只是构图的一个方式(条件)。此题注意编号(原图1--k是目标,后面是

    牛(起点)。)


    #include<iostream>   //140ms, 1A
    #include<cstdio>
    #include<vector>
    #include<queue>
    using namespace std;
    int k,c,m;const int inf =0x3f3f3f3f;
    int a[250][250]; int minmax;
    int e[20000][3];int head[250];  //链式前向星二维数组表示法,0:to,1:pre,2:wight;
    void folyd()       //最短路不用说
    {
         for(int i=1;i<=k+c;i++)
           for(int j=1;j<=k+c;j++)
             for(int ii=1;ii<=k+c;ii++)
                {
                    if(a[j][ii]>a[j][i]+a[i][ii])
                    {
                        a[j][ii]=a[j][i]+a[i][ii];
                      if(a[j][ii]>minmax)minmax=a[j][ii];  //枚举上界
                    }
                }
    }
    void build(int limit)  //由限制,选小于之的路,重新构图
    {
        for(int i=0;i<=k+c+2;i++)
            head[i]=-1;
           int num=0;
         for(int i=c+1;i<=c+k;i++)   //超级汇点
         {
             e[num][0]=c+k+1;e[num][1]=head[i];head[i]=num;
             e[num++][2]=m;
             e[num][0]=i;e[num][1]=head[c+k+1];head[c+k+1]=num;
             e[num++][2]=0;
         }
          for(int i=1;i<=c;i++)  //超级源点
         {
             e[num][0]=0;e[num][1]=head[i];head[i]=num;
             e[num++][2]=0;
             e[num][0]=i;e[num][1]=head[0];head[0]=num;
             e[num++][2]=1;
         }  
         for(int i=1;i<=k;i++)  //其他点
            for(int j=k+1;j<=k+c;j++)
               if(a[i][j]<=limit)
                 {
                     e[num][0]=j-k;e[num][1]=head[i+c];head[i+c]=num;
                     e[num++][2]=0;
                     e[num][0]=i+c;e[num][1]=head[j-k];head[j-k]=num;
                     e[num++][2]=1;
                 }
    }
    int level[250];int vis[250];
    bool bfs()                        //bfs+dfs,dinic算法
    {
        for(int i=0;i<=k+c+1;i++)
           vis[i]=level[i]=0;
        queue<int>q;
        q.push(0);vis[0]=1;
        while(!q.empty())
        {
          int cur=q.front();q.pop();
          for(int i=head[cur];i!=-1;i=e[i][1])
              {    int to=e[i][0];
                  if(!vis[to]&&e[i][2]>0)
                  {
                      vis[to]=1;
                      level[to]=level[cur]+1;
                      if(to==k+c+1)return 1;
                      q.push(to);
                  }
              }
        }
        return vis[k+c+1];
    }
    int dfs(int uu,int minf)            
    {
        if(uu==k+c+1||minf==0)return minf;
        int sum=0,f;
         for(int i=head[uu];i!=-1&&minf;i=e[i][1])
              {    int to=e[i][0];
                  if(level[to]==level[uu]+1&&e[i][2]>0)
                  {
                      f=dfs(to,minf<e[i][2]?minf:e[i][2]);
                      e[i][2]-=f;e[i^1][2]+=f;
                      sum+=f;minf-=f;
                  }
              }
          return sum;
    }
    bool check(int limit)
    {
        build(limit);
        int sumflow=0;
        while(bfs())
        {
            sumflow+=dfs(0,inf);
        }
        if(sumflow==c)   //所有牛可以去才是对
          return 1;
       return 0;
    }
    int main()
    {
        scanf("%d%d%d",&k,&c,&m);
        for(int i=1;i<=k+c;i++)
           for(int j=1;j<=k+c;j++)
            {
                int temp1;
                scanf("%d",&temp1);
                if(temp1==0)a[i][j]=inf;
                else a[i][j]=temp1;
            }
          folyd();
          int left=0,right=minmax,mid;
          while(right>left+1)      //二分答案,注意一下
          {
              mid=(right+left)/2;
              if(check(mid))
              {
                  right=mid;
              }
              else
                left=mid;
          }
          if(check(right-1))    //最后二分时判断特殊情况
          printf("%d
    ",right-1);
          else
            printf("%d
    ",right);
    
    }
    


  • 相关阅读:
    nltk.probability.FreqDist 自动识别语料库中词汇的频率分布
    wwsearch 全文检索引擎
    构建倒排索引快速减速
    Time-NLP---中文时间表达词转换---统一抽取段落中的时间信息
    根据传统的TFIDF快速进行相似性匹配
    delphi:函数大全 2(SysUtils.pas)(转载)
    delphi:函数大全 1(StrUtils.pas)(转载)
    GPS:中央子午线(转载)
    GPS:常用坐标系
    delphi:常用系统函数(转载)
  • 原文地址:https://www.cnblogs.com/yezekun/p/3925745.html
Copyright © 2020-2023  润新知