zoukankan      html  css  js  c++  java
  • hdu 4289 最大流拆点

    大致题意:
        给出一个又n个点,m条边组成的无向图。给出两个点s,t。对于图中的每个点,去掉这个点都需要一定的花费。求至少多少花费才能使得s和t之间不连通。

    大致思路:
        最基础的拆点最大流,把每个点拆作两个点 i 和 i' 连接i->i'费用为去掉这个点的花费,如果原图中有一条边a->b则连接a'->b。对这个图求出最大流即可。

    画了个图,仔细看看似乎是这么回事

      1 //1002
      2 /*
      3 HDU 4289
      4 G++  62ms  1888K
      5 最大流
      6 SAP
      7 */
      8 #include<stdio.h>
      9 #include<iostream>
     10 #include<map>
     11 #include<set>
     12 #include<algorithm>
     13 #include<string.h>
     14 #include<stdlib.h>
     15 using namespace std;
     16 
     17 const int MAXN=5000;//点数的最大值
     18 const int MAXM=2500000;//边数的最大值
     19 const int INF=0x3f3f3f3f;
     20 
     21 struct Node
     22 {
     23     int from,to,next;
     24     int cap;
     25 }edge[MAXM];
     26 int tol;
     27 int head[MAXN];
     28 int dep[MAXN];
     29 int gap[MAXN];//gap[x]=y:说明残留网络中 dep[i]==x的个数为y
     30 
     31 int n;//点的实际个数,一定是总的点的个数,包括源点和汇点
     32 void init()
     33 {
     34     tol=0;
     35     memset(head,-1,sizeof(head));
     36 }
     37 void addedge(int u,int v,int w)
     38 {
     39     edge[tol].from=u;
     40     edge[tol].to=v;
     41     edge[tol].cap=w;
     42     edge[tol].next=head[u];
     43     head[u]=tol++;
     44     edge[tol].from=v;
     45     edge[tol].to=u;
     46     edge[tol].cap=0;
     47     edge[tol].next=head[v];
     48     head[v]=tol++;
     49 }
     50 void BFS(int start,int end)
     51 {
     52     memset(dep,-1,sizeof(dep));
     53     memset(gap,0,sizeof(gap));
     54     gap[0]=1;
     55     int que[MAXN];
     56     int front,rear;
     57     front=rear=0;
     58     dep[end]=0;
     59     que[rear++]=end;
     60     while(front!=rear)
     61     {
     62         int u=que[front++];
     63         if(front==MAXN)front=0;
     64         for(int i=head[u];i!=-1;i=edge[i].next)
     65         {
     66             int v=edge[i].to;
     67             if(edge[i].cap!=0||dep[v]!=-1)continue;
     68             que[rear++]=v;
     69             if(rear==MAXN)rear=0;
     70             dep[v]=dep[u]+1;
     71             ++gap[dep[v]];
     72         }
     73     }
     74 }
     75 int SAP(int start,int end)
     76 {
     77     int res=0;
     78     BFS(start,end);
     79     int cur[MAXN];
     80     int S[MAXN];
     81     int top=0;
     82     memcpy(cur,head,sizeof(head));
     83     int u=start;
     84     int i;
     85     while(dep[start]<n)
     86     {
     87         if(u==end)
     88         {
     89             int temp=INF;
     90             int inser;
     91             for(i=0;i<top;i++)
     92                if(temp>edge[S[i]].cap)
     93                {
     94                    temp=edge[S[i]].cap;
     95                    inser=i;
     96                }
     97             for(i=0;i<top;i++)
     98             {
     99                 edge[S[i]].cap-=temp;
    100                 edge[S[i]^1].cap+=temp;
    101             }
    102             res+=temp;
    103             top=inser;
    104             u=edge[S[top]].from;
    105         }
    106         if(u!=end&&gap[dep[u]-1]==0)//出现断层,无增广路
    107           break;
    108         for(i=cur[u];i!=-1;i=edge[i].next)
    109            if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1)
    110              break;
    111         if(i!=-1)
    112         {
    113             cur[u]=i;
    114             S[top++]=i;
    115             u=edge[i].to;
    116         }
    117         else
    118         {
    119             int min=n;
    120             for(i=head[u];i!=-1;i=edge[i].next)
    121             {
    122                 if(edge[i].cap==0)continue;
    123                 if(min>dep[edge[i].to])
    124                 {
    125                     min=dep[edge[i].to];
    126                     cur[u]=i;
    127                 }
    128             }
    129             --gap[dep[u]];
    130             dep[u]=min+1;
    131             ++gap[dep[u]];
    132             if(u!=start)
    133               u=edge[S[--top]].from;
    134         }
    135 
    136     }
    137     return res;
    138 }
    139 
    140 int main()
    141 {
    142     //freopen("B.in","r",stdin);
    143     //freopen("B.out","w",stdout);
    144     int N,M;
    145     int u,v;
    146     int start;
    147     int end;
    148     while(scanf("%d%d",&N,&M)!=EOF)
    149     {
    150         init();
    151         scanf("%d%d",&start,&end);
    152         start=2*start-1;
    153         end=2*end;
    154         n=2*N;
    155         for(int i=1;i<=N;i++)
    156         {
    157             scanf("%d",&u);
    158             addedge(2*i-1,2*i,u);
    159             addedge(2*i,2*i-1,u);
    160         }
    161         while(M--)
    162         {
    163             scanf("%d%d",&u,&v);
    164             addedge(2*u,2*v-1,INF);
    165             addedge(2*v,2*u-1,INF);//这里一定要注意
    166         }
    167         printf("%d
    ",SAP(start,end));
    168     }
    169     return 0;
    170 }
  • 相关阅读:
    [Linux] crontab和shell每天定时备份数据库
    [Go] 实战项目在线客服GO-FLY -在gin框架使用IP识别库转换IP为城市
    [javascript] elementui和vue下复制粘贴上传图片
    [Go] GO-FLY客服项目被公众号 "转角遇到GitHub " 推荐
    [javascript] cdn模式下vue和vue-router实现路由
    [Go] Golang发送http GET请求
    [MySQL] 利用explain查看sql语句中使用的哪个索引
    [Go]GO语言实战-小程序或公众号接口gin框架验证微信服务器消息签名-开源WEB客服
    [Go]GO语言实战-开源WEB客服GO-FLY-gorm下分页的实现
    [前端] 设定为disabled的表单域值不能被提交
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4356821.html
Copyright © 2011-2022 走看看