• [网络流24题] 数字梯形问题 (费用流)


    洛谷传送门 LOJ传送门

    劳资把$spfa$里$cost$数组初始化从$-1$改成$-inf$就特么$A$了,梯形里有负数,浪费了半个多小时,心态都崩了

    问题难度好像是反过来的

    源点向第一排的点都流量为$1$,费用为$0$的边,最后一排的点向汇点连流量为$1$,费用为$0$的边

    第三问点点之间流量$inf$,费用为指向的点的权值

    第二问没啥好说的,点点之间的边流量改成$1$就行了

    因为最后一排可能有很多点,所以最后一排的点向汇点的流量改成$inf$

    第一问拆点

    一个点不能被走$2$次,在拆开点之间连流量为$1$,费用为它权值的边

    一条边不能被走$2$次,某点的出点向它能走的点的入点连流量为$1$,费用为$0$的边

    然后瞎**跑最大费用最大流就行了

    【暴躁!!】

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #define L1 55
      5 #define N1 1610
      6 #define M1 40010
      7 #define ll long long
      8 #define dd double
      9 #define inf 0x3f3f3f3f
     10 using namespace std;
     11 
     12 int gint()
     13 {
     14     int ret=0,fh=1;char c=getchar();
     15     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
     16     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
     17     return ret*fh;
     18 }
     19 struct Edge{
     20 int head[N1],to[M1<<1],nxt[M1<<1],flow[M1<<1],cost[M1<<1],cte;
     21 void ae(int u,int v,int F,int C)
     22 {
     23     cte++; to[cte]=v; flow[cte]=F; cost[cte]=C;
     24     nxt[cte]=head[u]; head[u]=cte;
     25 }
     26 }e,E;
     27 int K,n,m,cnt,S,T;
     28 int a[N1],que[M1<<1],hd,tl,cost[N1],flow[N1],use[N1],id[N1];
     29 int spfa()
     30 {
     31     int x,j,v;
     32     memset(flow,0,sizeof(flow)); 
     33     for(j=S;j<=T;j++) 
     34         cost[j]=-inf;
     35     hd=1,tl=0; que[++tl]=S; cost[S]=0; flow[S]=inf; use[S]=1;
     36     while(hd<=tl)
     37     {
     38         x=que[hd++];
     39         for(j=e.head[x];j;j=e.nxt[j])
     40         {
     41             v=e.to[j]; 
     42             if( cost[v]<cost[x]+e.cost[j] && e.flow[j]>0 )
     43             {
     44                 cost[v]=cost[x]+e.cost[j]; id[v]=j; 
     45                 flow[v]=min(flow[x],e.flow[j]);
     46                 if(!use[v]) que[++tl]=v, use[v]=1;
     47             }
     48         }
     49         use[x]=0;
     50     }
     51     return cost[T]!=-inf;
     52 }
     53 int EK()
     54 {
     55     int x,fl,tcost=0,i,j;
     56     while(spfa())
     57     {
     58         fl=flow[T]; tcost+=fl*cost[T]; 
     59         for(x=T;x!=S;x=e.to[id[x]^1])
     60         {
     61             e.flow[id[x]]-=fl;
     62             e.flow[id[x]^1]+=fl;
     63         }
     64     }
     65     return tcost;
     66 }
     67 
     68 int mp[L1][L1],idd[L1][L1];
     69 int check(int x,int y){
     70     if(x<1||y<1||x>n||y>m+x-1) return 0; return 1;
     71 }
     72 
     73 namespace S1{
     74 void solve()
     75 {
     76     int i,j,da,db; 
     77     memset(&e,0,sizeof(e)); e.cte=1;
     78     for(i=1;i<=n;i++) for(j=1;j<=m+i-1;j++) 
     79     {
     80         da=idd[i][j];
     81         e.ae(da,da+cnt,1,mp[i][j]); e.ae(da+cnt,da,0,-mp[i][j]);
     82         if(check(i+1,j)) { db=idd[i+1][j]; e.ae(da+cnt,db,1,0); e.ae(db,da+cnt,0,0); }
     83         if(check(i+1,j+1)){ db=idd[i+1][j+1]; e.ae(da+cnt,db,1,0); e.ae(db,da+cnt,0,0); }
     84     }
     85     for(i=1;i<=m;i++) e.ae(S,i,1,0), e.ae(i,S,0,0);
     86     for(i=1;i<=n+m-1;i++) e.ae(idd[n][i]+cnt,T,1,0), e.ae(T,idd[n][i]+cnt,0,0);
     87     printf("%d
    ",EK());
     88 }
     89 };
     90 
     91 namespace S2{
     92 void solve()
     93 {
     94     int i,j,da,db; 
     95     memset(&e,0,sizeof(e)); e.cte=1;
     96     for(i=1;i<n;i++) for(j=1;j<=m+i-1;j++) 
     97     {
     98         da=idd[i][j];
     99         db=idd[i+1][j]; e.ae(da,db,1,mp[i+1][j]); e.ae(db,da,0,-mp[i+1][j]); 
    100         db=idd[i+1][j+1]; e.ae(da,db,1,mp[i+1][j+1]); e.ae(db,da,0,-mp[i+1][j+1]);
    101     }
    102     for(i=1;i<=m;i++) e.ae(S,i,1,mp[1][i]), e.ae(i,S,0,-mp[1][i]);
    103     for(i=1;i<=n+m-1;i++) e.ae(idd[n][i],T,inf,0), e.ae(T,idd[n][i],0,0);
    104     printf("%d
    ",EK());
    105 }
    106 };
    107 
    108 namespace S3{
    109 void solve()
    110 {
    111     int i,j,da,db; 
    112     memset(&e,0,sizeof(e)); e.cte=1;
    113     for(i=1;i<=n;i++) for(j=1;j<=m+i-1;j++) 
    114     {
    115         da=idd[i][j];
    116         e.ae(da,da+cnt,inf,mp[i][j]); e.ae(da+cnt,da,0,-mp[i][j]);
    117         if(check(i+1,j)) { db=idd[i+1][j]; e.ae(da+cnt,db,inf,0); e.ae(db,da+cnt,0,0); }
    118         if(check(i+1,j+1)){ db=idd[i+1][j+1]; e.ae(da+cnt,db,inf,0); e.ae(db,da+cnt,0,0); }
    119     }
    120     for(i=1;i<=m;i++) e.ae(S,i,1,0), e.ae(i,S,0,0);
    121     for(i=1;i<=n+m-1;i++) e.ae(idd[n][i]+cnt,T,inf,0), e.ae(T,idd[n][i]+cnt,0,0);
    122     printf("%d
    ",EK());
    123 }
    124 };
    125 
    126 int main()
    127 {
    128     int i,j,da,db; 
    129     scanf("%d%d",&m,&n); 
    130     for(i=1;i<=n;i++) for(j=1;j<=m+i-1;j++) mp[i][j]=gint(),idd[i][j]=++cnt;
    131     S=0; T=2*cnt+1; S1::solve(); S2::solve(); S3::solve();
    132     return 0;
    133 }
  • 相关阅读:
    IP通信基础学习第八周
    IP通信基础学习第七周(下)
    IP通信基础学习第七周(上)
    IP通信基础学习第六周(下)
    mysql 笔记
    一个不错的MYSQL数据库备份类,PHP版,一个文件,精简版
    Linux下apache日志(按日期存放)分析与状态查看方法
    呵呵
    docker-compose常用命令
    mysql 数据备份
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10295355.html
Copyright © 2020-2023  润新知