zoukankan      html  css  js  c++  java
  • [网络流24题] 数字梯形问题

    题面:

    传送门

    思路:

    三合一题目

    但是实际上做好了第一个就没有别的问题了

    第一问:

    把每个数字拆成两个点,中间连一条容量为1,费用为0的边,以此达到限制每个点流量的目的

    然后其余的不多说,源点到第一层,每一层向下连,最后一层到汇点

    第二问:

    第一问中每个点内部的那条边容量改成inf就好

    第三问:

    直接dp算了......当然你也可以再改改边,跑网络流,不过估计没有dp快

    Code:

      1     #include<iostream>
      2     #include<cstdio>
      3     #include<cstring>
      4     #include<algorithm>
      5     #define inf 1000000000
      6     using namespace std;
      7     inline int read(){
      8         int re=0,flag=1;char ch=getchar();
      9         while(ch>'9'||ch<'0'){
     10             if(ch=='-') flag=-1;
     11             ch=getchar();
     12         }
     13         while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
     14         return re;
     15     }
     16     int n,m,cnt,ans,flow,tot,first[10010],x[25][25],id[25][25];
     17     int dis[10010],pre[10010],path[10010];
     18     struct edge{
     19         int to,next,w,cap;
     20     }a[100010];
     21     inline void add(int u,int v,int w,int cap){
     22     //    cout<<"add "<<u<<ends<<v<<ends<<w<<ends<<cap<<endl;
     23         a[++cnt]=(edge){v,first[u],w,cap};first[u]=cnt;
     24         a[++cnt]=(edge){u,first[v],-w,0};first[v]=cnt;
     25     }
     26     void init(){
     27         memset(first,-1,sizeof(first));
     28         memset(a,0,sizeof(a));cnt=-1;ans=0;flow=0;
     29     }
     30     int spfa(int s,int t){
     31         int q[10010],head=0,tail=1,maxn=10000,i,u,v,w;
     32         memset(pre,-1,sizeof(pre));
     33         for(i=s;i<=t;i++) dis[i]=inf;
     34         q[0]=s;dis[s]=0;
     35         while(head!=tail){
     36             u=q[head];head=(head+1)%maxn;
     37     //        cout<<"spfa "<<u<<endl;
     38             for(i=first[u];~i;i=a[i].next){
     39                 v=a[i].to;w=a[i].w;
     40     //            cout<<"    to "<<v<<ends<<dis[v]<<ends<<w+dis[u]<<endl;
     41                 if(a[i].cap&&dis[v]>dis[u]+w){
     42                     dis[v]=dis[u]+w;
     43                     pre[v]=u;path[v]=i;
     44                     q[tail]=v;tail=(tail+1)%maxn;
     45                 }
     46             }
     47         }
     48         return ~pre[t];
     49     }
     50     inline int _min(int l,int r){return (l<r)?l:r;}
     51     int mcmf(int s,int t){
     52         int f,u;
     53         while(spfa(s,t)){
     54             f=inf;
     55             for(u=t;u!=s;u=pre[u]) f=_min(f,a[path[u]].cap);
     56             flow+=f;ans+=dis[t]*f;
     57     //        cout<<"mcmf "<<flow<<ends<<ans<<endl;
     58             for(u=t;u!=s;u=pre[u]){
     59                 a[path[u]].cap-=f;
     60                 a[path[u]^1].cap+=f;
     61             }
     62         }
     63     }
     64     int main(){
     65         freopen("digit.in","r",stdin);
     66         freopen("digit.out","w",stdout);
     67         int i,j;
     68         n=read();m=read();
     69         for(i=1;i<=m;i++){
     70             for(j=1;j<=i+n-1;j++) x[i][j]=read(),id[i][j]=++tot;
     71         }
     72         //T1
     73         init();
     74         for(i=1;i<=n;i++) add(0,id[1][i],0,1);
     75         for(i=1;i<=m;i++){
     76             for(j=1;j<=i+n-1;j++) add(id[i][j],id[i][j]+tot,0,1);
     77         }
     78         for(i=1;i<m;i++){
     79             for(j=1;j<=i+n-1;j++){
     80                 add(id[i][j]+tot,id[i+1][j],-x[i][j],1);
     81                 add(id[i][j]+tot,id[i+1][j+1],-x[i][j],1);
     82             }
     83         }
     84         for(i=1;i<=n+m-1;i++) add(id[m][i]+tot,(tot<<1)+1,-x[m][i],1);
     85         mcmf(0,(tot<<1)+1);
     86         printf("%d
    ",-ans);
     87         //T2
     88         init();
     89         for(i=1;i<=n;i++) add(0,id[1][i],0,1);
     90         for(i=1;i<=m;i++){
     91             for(j=1;j<=i+n-1;j++) add(id[i][j],id[i][j]+tot,0,inf);
     92         }
     93         for(i=1;i<m;i++){
     94             for(j=1;j<=i+n-1;j++){
     95                 add(id[i][j]+tot,id[i+1][j],-x[i][j],1);
     96                 add(id[i][j]+tot,id[i+1][j+1],-x[i][j],1);
     97             }
     98         }
     99         for(i=1;i<=n+m-1;i++) add(id[m][i]+tot,(tot<<1)+1,-x[m][i],inf);
    100         mcmf(0,(tot<<1)+1);
    101         printf("%d
    ",-ans);
    102         //T3
    103         init();
    104         for(i=1;i<=n;i++) add(0,id[1][i],0,1);
    105         for(i=1;i<=m;i++){
    106             for(j=1;j<=i+n-1;j++) add(id[i][j],id[i][j]+tot,0,inf);
    107         }
    108         for(i=1;i<m;i++){
    109             for(j=1;j<=i+n-1;j++){
    110                 add(id[i][j]+tot,id[i+1][j],-x[i][j],inf);
    111                 add(id[i][j]+tot,id[i+1][j+1],-x[i][j],inf);
    112             }
    113         }
    114         for(i=1;i<=n+m-1;i++) add(id[m][i]+tot,(tot<<1)+1,-x[m][i],inf);
    115         mcmf(0,(tot<<1)+1);
    116         printf("%d",-ans);
    117     }
  • 相关阅读:
    扩展正则表达式 练习题
    Linux特殊符号
    文件属性下
    文件属性和ls -lhi
    复习之前的和补充一些内容
    第二关练习题总结完结
    云服务器防ssh攻击
    实验四+085
    实验3+085
    第5次作业+085
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8454475.html
Copyright © 2011-2022 走看看