[网络流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\n",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\n",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\n",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 }

 

posted @ 2019-01-20 16:41  guapisolo  阅读(134)  评论(0编辑  收藏  举报