• poj 2455(二分+最大流)


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

    思路:求1-n的路径中最长段的最小值,显然要用到二分,我们二分最长段,如果当前u,v的距离小于等于limit,则连边(双向边),边容量为1,代表只能走1次。然后就是以1为源点,n为汇点跑最大流,如果maxflow>=T,则在(low,mid)中搜索,否则就在(mid,high)中搜索。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 using namespace std;
      7 #define MAXN 444
      8 #define MAXM 44444444
      9 #define inf 1<<30
     10 
     11 struct Edge{
     12     int v,cap,next;
     13 }edge[MAXM];
     14 
     15 struct E{
     16     int u,v,w;
     17 }e[MAXN*MAXN];
     18 
     19 int n,m,T,NE,NV;
     20 int head[MAXN];
     21 
     22 void Insert(int u,int v,int cap)
     23 {
     24     edge[NE].v=v;
     25     edge[NE].cap=cap;
     26     edge[NE].next=head[u];
     27     head[u]=NE++;
     28 
     29     edge[NE].v=u;
     30     edge[NE].cap=0;
     31     edge[NE].next=head[v];
     32     head[v]=NE++;
     33 }
     34 
     35 int level[MAXN],gap[MAXN];
     36 void bfs(int vt)
     37 {
     38     memset(level,-1,sizeof(level));
     39     memset(gap,0,sizeof(gap));
     40     level[vt]=0;
     41     gap[level[vt]]++;
     42     queue<int>que;
     43     que.push(vt);
     44     while(!que.empty()){
     45         int u=que.front();
     46         que.pop();
     47         for(int i=head[u];i!=-1;i=edge[i].next){
     48             int v=edge[i].v;
     49             if(level[v]<0){
     50                 level[v]=level[u]+1;
     51                 gap[level[v]]++;
     52                 que.push(v);
     53             }
     54         }
     55     }
     56 }
     57 
     58 int pre[MAXN],cur[MAXN];
     59 int SAP(int vs,int vt)
     60 {
     61     bfs(vt);
     62     memset(pre,-1,sizeof(pre));
     63     memcpy(cur,head,sizeof(head));
     64     int maxflow=0,aug=inf;
     65     int u=pre[vs]=vs;
     66     gap[0]=NV;
     67     while(level[vs]<NV){
     68         bool flag=false;
     69         for(int &i=cur[u];i!=-1;i=edge[i].next){
     70             int v=edge[i].v;
     71             if(edge[i].cap>0&&level[u]==level[v]+1){
     72                 flag=true;
     73                 pre[v]=u;
     74                 u=v;
     75                 aug=min(aug,edge[i].cap);
     76                 if(v==vt){
     77                     maxflow+=aug;
     78                     for(u=pre[v];v!=vs;v=u,u=pre[u]){
     79                         edge[cur[u]].cap-=aug;
     80                         edge[cur[u]^1].cap+=aug;
     81                     }
     82                     aug=inf;
     83                 }
     84                 break;
     85             }
     86         }
     87         if(flag)continue;
     88         int minlevel=NV;
     89         for(int i=head[u];i!=-1;i=edge[i].next){
     90             int v=edge[i].v;
     91             if(edge[i].cap>0&&level[v]<minlevel){
     92                 minlevel=level[v];
     93                 cur[u]=i;
     94             }
     95         }
     96         if(--gap[level[u]]==0)break;
     97         level[u]=minlevel+1;
     98         gap[level[u]]++;
     99         u=pre[u];
    100     }
    101     return maxflow;
    102 }
    103 
    104 
    105 void Build(int limit)
    106 {
    107     NE=0;
    108     memset(head,-1,sizeof(head));
    109     for(int i=1;i<=m;i++){
    110         if(e[i].w<=limit){
    111             Insert(e[i].u,e[i].v,1);
    112             Insert(e[i].v,e[i].u,1);
    113         }
    114     }
    115 }
    116 
    117 
    118 int main()
    119 {
    120     int low,high,mid,MIN,limit,u,v,w;
    121     while(~scanf("%d%d%d",&n,&m,&T)){
    122         limit=0;
    123         for(int i=1;i<=m;i++){
    124             scanf("%d%d%d",&u,&v,&w);
    125             e[i].u=u,e[i].v=v,e[i].w=w;
    126             limit=max(limit,w);
    127         }
    128         NV=n;
    129         low=0,high=limit+1,MIN=0;
    130         while(low<=high){
    131             mid=(low+high)>>1;
    132             Build(mid);
    133             if(SAP(1,n)>=T){
    134                 MIN=mid;
    135                 high=mid-1;
    136             }else
    137                 low=mid+1;
    138         }
    139         printf("%d
    ",MIN);
    140     }
    141     return 0;
    142 }
    View Code
  • 相关阅读:
    Java 基础练习:控制台画圆,画等腰三角,乘法表
    Java 控制台五子棋游戏
    Java浮点数转化为人民币读法字符串
    Java Arrays类的用法
    Java javadoc使用
    Android 使用Camera2 调用摄像头显示预览与拍照
    SSRS: How to Display Checkbox on Report
    ADFS部署过程中设置network service对证书的读取权限
    Dynamics CRM2013 ScLib::AccessCheckEx failed
    ADFS3.0 Customizing the AD FS Sign-in Pages
  • 原文地址:https://www.cnblogs.com/wally/p/3279178.html
Copyright © 2020-2023  润新知