zoukankan      html  css  js  c++  java
  • hdu2686/hdu3376 最小费用流最大流 拆点

      虽然题目求的是最大费用,但是我们可以通过转换就变为最小费用。用一个比最大值更的数与每个数的差作为费用值。最后处理回来就i可以了。有些人用直接每个值都乘以-1,这样更简单。

      做这题,我对为什么不拆点就会错这个问题想了很久,也问了一些人。最后得出了一些知识。

      在《挑战程序设计竞赛》的214页有讲。

      点有容量限制,就必须拆点来实现。

      3
      1 1 0
      1 1 1
      0 1 1
      在这组数据中,我们按从左到右,从上到下的顺序标出点的序号。
      1 → 2    3
      ↓    ↓
      4 → 5 → 6
            ↓    ↓
      7    8 → 9
      不拆点建图,是有两条路径的。但是5这个点被经过了2次,只有一条路径。点只能经过一次没有体现出来。

      所以需要拆点。怎么拆了?像这样。

      1 → 2    3
      ↓    ↓
      4 → 

           ↓

        10→ 6
            ↓    ↓
      7    8 → 9

      这样5 →  10的容量限制为1时,就能限制5这个点的容量为1了。

    下面是hdu3376的代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<queue>
      5 #include<algorithm>
      6 using namespace std;
      7 const int N =1000010, M=4000100,INF=0x3f3f3f3f;
      8 struct node
      9 {
     10     int to, next, c ,f;//c是容量,f是费用
     11 }edge[M];
     12 int head[N],dis[N],load[N],p[N];
     13 bool vis[N];
     14 int tot,flow,cost;
     15 bool spfa(int S, int E,int n)
     16 {
     17     queue<int > que;
     18     memset(vis,0,sizeof(vis));
     19     memset(load,-1,sizeof(load));
     20     memset(p,-1,sizeof(p));
     21     for(int i=0;i<=n;i++)
     22         dis[i]=INF;
     23     que.push(S);
     24     dis[S]=0;
     25     vis[S]=1;
     26     while(!que.empty())
     27     {
     28         int u=que.front();
     29         que.pop();
     30         vis[u]=0;
     31         for(int i=head[u];i!=-1;i=edge[i].next)
     32         {
     33             if(edge[i].c)
     34             {
     35                 int v=edge[i].to;
     36                 if(dis[v]-dis[u]>edge[i].f)
     37                 {
     38                     dis[v]=dis[u]+edge[i].f;
     39                     p[v]=u;
     40                     load[v]=i;
     41                     if(!vis[v])
     42                     {
     43                         vis[v]=1;
     44                         que.push(v);
     45                     }
     46                 }
     47             }
     48         }
     49     }
     50     if(dis[E]==INF) return 0;
     51     return 1;
     52 }
     53 void MCF(int S, int E,int n)
     54 {
     55     int u,mn;
     56     flow=cost=0;
     57     while(spfa(S,E,n))
     58     {
     59         u=E; mn=INF;
     60         while(p[u]!=-1)
     61         {
     62             mn=min(edge[load[u]].c, mn);
     63             u=p[u];
     64         }
     65         u=E;
     66         while(p[u]!=-1)
     67         {
     68             edge[load[u]].c-=mn;
     69             edge[load[u]^1].c+=mn;
     70             u=p[u];
     71         }
     72         cost+=dis[E]*mn;
     73         flow+=mn;
     74     }
     75 }
     76 void addedge(int a,int b,int c,int d)
     77 {
     78     edge[tot].to=b;edge[tot].c=c;edge[tot].f=d;
     79     edge[tot].next=head[a];head[a]=tot++;
     80     edge[tot].to=a;edge[tot].c=0;edge[tot].f=-d;
     81     edge[tot].next=head[b];head[b]=tot++;
     82 }
     83 void init()
     84 {
     85     tot=0;
     86     memset(head,-1,sizeof(head));
     87 }
     88 int nd[N];
     89 int main()
     90 {
     91     //freopen("test.txt","r",stdin);
     92     int n,i,j,k,a,s,e,b;
     93     while(scanf("%d",&n)!=EOF)
     94     {
     95         init();
     96         b=n*n;
     97         s=2*b+1;e=s+1; a=100;
     98         for(i=1;i<=b;i++) {scanf("%d",&nd[i]);a=max(a,nd[i]);}
     99         a++;
    100         addedge(s,1,2,0);
    101         addedge(2*b,e,2,0);
    102         for(i=1;i<=b;i++)
    103         {
    104             if(i==1) addedge(i,i+b,2,a-nd[i]);
    105             else if(i==b) addedge(i,i+b,2,a-nd[i]);
    106             else addedge(i,i+b,1,a-nd[i]);
    107             if(i%n) addedge(i+b,i+1,1,0);//向右
    108             if(i<=b-n) addedge(i+b,i+n,1,0);//向下
    109         }
    110         MCF(s,e,e);
    111         cost-=a-nd[1]+a-nd[b];
    112         int ans=4*a*(n-1)-cost;
    113         printf("%d
    ",ans);
    114     }
    115     return 0;
    116 }
    View Code
  • 相关阅读:
    localStorage和sessionStorage的使用方法和一些特性介绍
    python 图片添加水印 pdf 添加水印
    python kayb算法之从一组序列当中获取一组与目标值最接近的算法
    python 中将字符串加载为公钥
    Python中rsa模块【sign 加签验签】的使用
    python中openpyxl的用法【安装,以及一些基本的操作, xlwt教程链接】
    python当中的坑【闭包与lambda】
    python函数参数中带有默认参数list的坑
    Django中辅助技术总结[静态文件,中间件,上传图片,分页案例]
    Django中视图总结[urls匹配,HttpRequest对象,HttpResponse对象,对象序列化接受及案例]
  • 原文地址:https://www.cnblogs.com/Potato-lover/p/3978405.html
Copyright © 2011-2022 走看看