• 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
    ",binary_solve());
    96     }
    97     return 0;
    98 }

    2018-11-24

  • 相关阅读:
    GitHub上创建项目
    html5的标签中,哪些是行内元素,哪些是块级元素。
    盒子模型及其他的层次结构关系
    二维码生成
    SSH整合笔记
    Spring回顾
    struts2 测试错题解析
    Java Script基础
    Java OOP考试错题分析
    接口的用法及注意点
  • 原文地址:https://www.cnblogs.com/00isok/p/10014113.html
Copyright © 2020-2023  润新知