zoukankan      html  css  js  c++  java
  • HDU 4289 Control [网络流拆点]

      图上的每个点有权值,求使从起点无法到达终点去掉的权值和最小。

      因为权值在点上,所以要进行拆点。将i点拆为2i和2i+1。然后流量统一从偶数点进,奇数点出,点之间连流量为点权的有向边,无向边拆成两条有向边,分别向两个端点连两条流量为无穷大的有向边,如下图所示。

     1 #include <string.h>
     2 #include <stdio.h>
     3 #include <algorithm>
     4 #define MAXN 500
     5 #define MAXE 100000
     6 #define INF 0x3f3f3f3f
     7 struct edge{
     8     int v,e,n,flow;
     9 }e[MAXE];
    10 int first[MAXN],es;
    11 int work[MAXN],q[MAXN],d[MAXN],front,rear;
    12 void addedge(int u,int v,int flow){
    13     e[es].v=v,e[es].flow=flow,e[es].n=first[u],first[u]=es++;
    14 }
    15 int bfs(int s,int t,int n){
    16     memset(d,-1,sizeof(d[0])*(n+1));
    17     q[front=rear=d[s]=0]=s,rear++;
    18     while(front<rear){
    19         int u=q[front++];
    20         for(int i=first[u];i!=-1;i=e[i].n)
    21             if(e[i].flow&&d[e[i].v]==-1){
    22                 d[e[i].v]=d[u]+1,q[rear++]=e[i].v;
    23                 if(e[i].v==t)return 1;
    24             }
    25     }
    26     return 0;
    27 }
    28 int dfs(int cur,int t,int res){
    29     if(cur==t)return res;
    30     for(int &i=work[cur];i!=-1;i=e[i].n)
    31         if(e[i].flow&&d[e[i].v]==d[cur]+1)
    32             if(int tmp=dfs(e[i].v,t,std::min(res,e[i].flow))){
    33                 e[i].flow-=tmp,e[i^1].flow+=tmp;
    34                 return tmp;
    35             }
    36     return 0;
    37 }
    38 int dinic(int s,int t,int n){
    39     int ans=0,tt;
    40     while(bfs(s,t,n)){
    41         memcpy(work,first,sizeof(first[0])*(n+1));
    42         while(tt=dfs(s,t,INF))ans+=tt;
    43     }
    44     return ans;
    45 }
    46 int n,m,s,t,ci,tu,tv,va;
    47 int main(){
    48     //freopen("test.in","r",stdin);
    49     while(scanf("%d%d",&n,&m)!=EOF){
    50         scanf("%d%d",&s,&t);
    51         int va=INF;
    52         memset(first,-1,sizeof first);es=0;
    53         for(int i=1;i<=n;i++){
    54             scanf("%d",&ci);
    55             addedge(i<<1,i<<1|1,ci);
    56             addedge(i<<1|1,i<<1,0);
    57             if(i==s||i==t)va=std::min(va,ci);
    58         }
    59         s=s<<1,t=t<<1|1;
    60         for(int i=0;i<m;i++){
    61             scanf("%d%d",&tu,&tv);
    62             addedge(tu<<1,tv<<1|1,0);
    63             addedge(tv<<1|1,tu<<1,INF);
    64             addedge(tv<<1,tu<<1|1,0);
    65             addedge(tu<<1|1,tv<<1,INF);
    66         }
    67         printf("%d\n",std::min(va,dinic(s,t,2*n+2)));
    68     }
    69 
    70     return 0;
    71 }
  • 相关阅读:
    老板也是一个工种,也是一种技能
    用上了ReSharper
    《钟馗伏魔:雪妖魔灵》另类解读
    内部培训-流程图培训
    未来价值是把信息从网上拿下来,而不是放上
    一个人的电影
    2015清明节假期纪实
    十年魔戒
    天使基金资金预期使用表
    项目过程中各阶段应交付的文档
  • 原文地址:https://www.cnblogs.com/swm8023/p/2694594.html
Copyright © 2011-2022 走看看