• 洛谷P4013 数字梯形问题(费用流)


    传送门

    两个感受:码量感人……大佬nb……

    规则一:$m$条路径都不相交,那么每一个点只能经过一次,那么考虑拆点,把每一个点拆成$A_{i,j}$和$B_{i,j}$,然后两点之间连一条容量$1$,费用该点本身数值的边,表明这个点只能被选一次,然后每一个点的$B$向它能到达的点的$A$连边,表明能从这个点到另一个点,容量随意,费用$0$,然后源点向第一排所有点的$A$连边,最后一排所有点的$B$向汇点连边,都是容量随意,费用$0$,然后跑一个最大费用流即可

    规则二:每一个点可以被选多次,那么不用拆点了,直接每一个点向它能到的点连边,容量$1$,表明一条边只能被选一次,费用为该点的数值,源点向第一排所有点连边,容量$1$,费用$0$,最后一排所有点向汇点连边,费用为该点的数值,然后跑一个最大费用流即可

    规则三:把每一条边只能选一次的限制去掉,总之就是除了源点到第一排的边,其他边的容量都改为$inf$,然后跑一个最大费用流

      1 //minamoto
      2 #include<bits/stdc++.h>
      3 #define inf 0x3f3f3f3f
      4 using namespace std;
      5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
      6 char buf[1<<21],*p1=buf,*p2=buf;
      7 inline int read(){
      8     #define num ch-'0'
      9     char ch;bool flag=0;int res;
     10     while(!isdigit(ch=getc()))
     11     (ch=='-')&&(flag=true);
     12     for(res=num;isdigit(ch=getc());res=res*10+num);
     13     (flag)&&(res=-res);
     14     #undef num
     15     return res;
     16 }
     17 const int N=10005,M=50005;
     18 int ver[M],head[N],flow[M],edge[M],Next[M],tot=1;
     19 int vis[N],dis[N],disf[N],Pre[N],last[N],s=0,t=10000;
     20 int a[25][55],b[25][55];
     21 queue<int> q;
     22 inline void add(int u,int v,int f,int e){
     23     ver[++tot]=v,Next[tot]=head[u],head[u]=tot,flow[tot]=f,edge[tot]=e;
     24     ver[++tot]=u,Next[tot]=head[v],head[v]=tot,flow[tot]=0,edge[tot]=-e;
     25 }
     26 bool spfa(){
     27     memset(dis,0xef,sizeof(dis));
     28     q.push(s),dis[s]=0,disf[s]=inf,Pre[t]=-1;
     29     while(!q.empty()){
     30         int u=q.front();q.pop();vis[u]=0;
     31         for(int i=head[u];i;i=Next[i]){
     32             int v=ver[i];
     33             if(flow[i]&&dis[v]<dis[u]+edge[i]){
     34                 dis[v]=dis[u]+edge[i],last[v]=i,Pre[v]=u;
     35                 disf[v]=min(disf[u],flow[i]);
     36                 if(!vis[v]) vis[v]=1,q.push(v);
     37             }
     38         }
     39     }
     40     return ~Pre[t];
     41 }
     42 int dinic(){
     43     int maxcost=0;
     44     while(spfa()){
     45         int u=t;
     46         maxcost+=disf[t]*dis[t];
     47         while(u!=s){
     48             flow[last[u]]-=disf[t];
     49             flow[last[u]^1]+=disf[t];
     50             u=Pre[u];
     51         }
     52     }
     53     return maxcost;
     54 }
     55 void clear(){
     56     tot=1,memset(head,0,sizeof(head));
     57 }
     58 int main(){
     59     int n,m,k,o,num=0;
     60     k=m=read(),n=read();
     61     o=((m<<1)+n-1)*n>>1;
     62     for(int i=1;i<=n;++i,++k)
     63     for(int j=1;j<=k;++j)
     64     a[i][j]=read(),b[i][j]=++num;
     65     k=m;
     66     for(int i=1;i<=k;++i)
     67     add(s,b[1][i],1,0);
     68     for(int i=1;i<n;++i,++k)
     69     for(int j=1;j<=k;++j){
     70         add(b[i][j],b[i][j]+o,1,a[i][j]);
     71         add(b[i][j]+o,b[i+1][j],1,0);
     72         add(b[i][j]+o,b[i+1][j+1],1,0);
     73     }
     74     for(int i=1;i<=k;++i){
     75         add(b[n][i],b[n][i]+o,1,a[n][i]);
     76         add(b[n][i]+o,t,1,0);
     77     }
     78     printf("%d
    ",dinic());
     79     clear();
     80     k=m;
     81     for(int i=1;i<=k;++i)
     82     add(s,b[1][i],1,0);
     83     for(int i=1;i<n;++i,++k)
     84     for(int j=1;j<=k;++j){
     85         add(b[i][j],b[i+1][j],1,a[i][j]);
     86         add(b[i][j],b[i+1][j+1],1,a[i][j]);
     87     }
     88     for(int i=1;i<=k;++i)
     89     add(b[n][i],t,inf,a[n][i]);
     90     printf("%d
    ",dinic());
     91     clear();
     92     k=m;
     93     for(int i=1;i<=m;++i) add(s,b[1][i],1,0);
     94     for(int i=1;i<n;++i,++k)
     95     for(int j=1;j<=k;++j){
     96         add(b[i][j],b[i+1][j],inf,a[i][j]);
     97         add(b[i][j],b[i+1][j+1],inf,a[i][j]);
     98     }
     99     for(int i=1;i<=k;++i) add(b[n][i],t,inf,a[n][i]);
    100     printf("%d
    ",dinic());
    101     return 0;
    102 }
  • 相关阅读:
    关于“平台”概念的解析
    学习新名词“MVP”(最简可行产品)
    Docker 部署Spring boot 项目如何优雅的关闭(Eureka下线)
    微服务健康监控方案
    Cpu飚高show-busy-java-threads一件脚本排查与Arthas线上诊断工具排查实战
    微服务发展规划(PS 大概分层未细化到具体系统)
    前后端分离研究
    Graphics2D画快递电子面单图片并且打印
    改写rm -rf 脚本
    检查系统信息脚本
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9507300.html
Copyright © 2020-2023  润新知