• $[Luogu]$ 洛谷 $P4013$ 题解【数字梯形问题】


    感动,终于过了(由此我发现了自己是有多么的菜……)

    其实其他几个发题解大佬都已经把思路讲的很清楚了,我就不细讲了,主要是提醒大家一下

    可能这一题的提交记录中也只有我交了这么多次,发了三篇讨论,连着改了一个星期吧……

    大致的思路:

      • 第一问要保证路径互不相交,也就是不能让一个点被经过多次

      • 是不是感觉很熟悉!是不是!没错,就是拆点大法!用拆点来保证只经过这个点一次即可QQwQ

      • 第二问仅不允许在路径上相交,就没必要拆点啦QQwQ

      • 同样的,用流量为1来保证路径只经过一次

      • 第三问一看……噢,这不相当于是没有限制么QQQQQwQ!

      • 激动的我们将流量开大并什么也不想管

    以下是我主要出问题的几个点(求不要嘲讽):

    • memset赋负数时只能赋-1,赋其他的数会变成奇怪的负数,所以在判断时要看他是否<0,否则就会出错……

    • 这一题不要看范围只有20就不开大数组范围,一定要开大!!,不然就会出现奇怪的错误,因为数组是连续的,所以一旦爆数组就会修改到其他几个数组然后就挂了……(像我就T到飞起……)

    之前我改代码是发现……题解中没有一篇Dinic递归的代码!

    于是给大家一个并手动普度众生

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 inline int read()
      4 {
      5     int f=1,w=0;char x=0;
      6     while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();}
      7     while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();}
      8     return f*w;
      9 }
     10 int head[200020],cur[200020],num_edge=-1;
     11 int a[1001][1001],b[1001][1001],cnt;
     12 int n,m,s,t,ans;
     13 struct Edge
     14 {
     15     int next,to,dis,cos;
     16 }edge[200020];
     17 inline void add(int from,int to,int dis,int cos)
     18 {
     19     edge[++num_edge].next=head[from];
     20     edge[num_edge].to=to;
     21     edge[num_edge].dis=dis;
     22     edge[num_edge].cos=cos;
     23     head[from]=num_edge;
     24 }
     25 inline void clear()
     26 {
     27     num_edge=-1;
     28     memset(head,-1,sizeof(head));
     29     ans=0;
     30 }
     31 int d[200000],v[200000],flo[200000];
     32 inline bool bfs()
     33 {
     34     memset(d,-50,sizeof(d));
     35     memset(v,0,sizeof(v));
     36     memset(flo,0,sizeof(flo));
     37     queue<int> q;
     38     q.push(s);
     39     d[s]=0;
     40     v[s]=1;flo[s]=1;
     41     while(!q.empty())
     42     {
     43         int x=q.front();
     44         q.pop();
     45         v[x]=0;
     46         for(int i=head[x];i!=-1;i=edge[i].next)
     47         {
     48             int y=edge[i].to;
     49             if(edge[i].dis>0&&d[y]<d[x]+edge[i].cos)
     50             {
     51                 d[y]=d[x]+edge[i].cos;
     52                 flo[y]=flo[x]+1;
     53                 if(!v[y]) { q.push(y); v[y]=1; }
     54             }
     55         }
     56     }
     57     if(d[t]<0) return 0;
     58     else return 1;
     59 }
     60 int dfs(int pos,int dis)
     61 {
     62     if(pos==t) return dis;
     63     for(int i=cur[pos];i!=-1;i=edge[i].next)
     64         if(flo[edge[i].to]==flo[pos]+1&&edge[i].dis!=0&&d[edge[i].to]==d[pos]+edge[i].cos)
     65         {
     66             int data=dfs(edge[i].to,min(dis,edge[i].dis));
     67             if(data>0)
     68             {
     69                 edge[i].dis-=data;
     70                 edge[i^1].dis+=data;
     71                 ans+=edge[i].cos;
     72                 cur[pos]=i;
     73                 return data; 
     74             }
     75         }
     76     return 0;
     77 }
     78 void  Dinic()
     79 {
     80     while(bfs())
     81     {
     82         memcpy(cur,head,sizeof(head));
     83         while(dfs(s,0x3f3f3f3f));
     84     }
     85 }
     86 int main(){
     87     memset(head,-1,sizeof(head));
     88     m=read();
     89     n=read();
     90     for(int i=1;i<=n;i++)
     91         for(int j=1;j<=m+i-1;j++)
     92             a[i][j]=read(),b[i][j]=++cnt;
     93     s=0;
     94     t=cnt*2+3;
     95     for(int i=1;i<=m;i++)
     96         add(s,b[1][i],1,0),add(b[1][i],s,0,0);
     97     for(int i=1;i<n;i++)
     98         for(int j=1;j<=m+i-1;j++)
     99         {
    100             add(b[i][j],b[i][j]+cnt,1,a[i][j]);
    101             add(b[i][j]+cnt,b[i][j],0,-a[i][j]);
    102             add(b[i][j]+cnt,b[i+1][j],1,0);
    103             add(b[i+1][j],b[i][j]+cnt,0,0);
    104             add(b[i][j]+cnt,b[i+1][j+1],1,0);
    105             add(b[i+1][j+1],b[i][j]+cnt,0,0);
    106         }
    107     for(int i=1;i<=m+n-1;i++)
    108     {
    109         add(b[n][i],b[n][i]+cnt,1,a[n][i]);
    110         add(b[n][i]+cnt,b[n][i],0,-a[n][i]);
    111         add(b[n][i]+cnt,t,1,0);
    112         add(t,b[n][i]+cnt,0,0);
    113     }
    114     Dinic();
    115     printf("%d
    ",ans);
    116     clear();
    117     for(int i=1;i<=m;i++)
    118         add(s,b[1][i],1,0),add(b[1][i],s,0,0);
    119     for(int i=1;i<n;i++)
    120         for(int j=1;j<=m+i-1;j++)
    121         {
    122             add(b[i][j],b[i+1][j],1,a[i][j]);
    123             add(b[i+1][j],b[i][j],0,-a[i][j]);
    124             add(b[i][j],b[i+1][j+1],1,a[i][j]);
    125             add(b[i+1][j+1],b[i][j],0,-a[i][j]);
    126         }
    127     for(int i=1;i<=m+n-1;i++)
    128     {
    129         add(b[n][i],t,0x3f3f3f3f,a[n][i]);
    130         add(t,b[n][i],0,-a[n][i]);
    131     }
    132     Dinic();
    133     printf("%d
    ",ans);
    134     clear();
    135     for(int i=1;i<=m;i++)
    136         add(s,b[1][i],1,0),add(b[1][i],s,0,0);
    137     for(int i=1;i<n;i++)
    138         for(int j=1;j<=m+i-1;j++)
    139         {
    140             add(b[i][j],b[i+1][j],0x3f3f3f3f,a[i][j]);
    141             add(b[i+1][j],b[i][j],0,-a[i][j]);
    142             add(b[i][j],b[i+1][j+1],0x3f3f3f3f,a[i][j]);
    143             add(b[i+1][j+1],b[i][j],0,-a[i][j]);
    144         }
    145     for(int i=1;i<=m+n-1;i++)
    146     {
    147         add(b[n][i],t,0x3f3f3f3f,a[n][i]);
    148         add(t,b[n][i],0,-a[n][i]);
    149     }
    150     Dinic();
    151     printf("%d
    ",ans);
    152 }
  • 相关阅读:
    跟我一起学习ASP.NET 4.5 MVC4.0(二)(转)
    跟我一起学习ASP.NET 4.5 MVC4.0(一)(转)
    MVC3 Razor视图引擎的基础语法
    了解ASP.NET MVC几种ActionResult的本质:HttpStatusCodeResult & RedirectResult/RedirectToRouteResult
    通过一个模拟程序让你明白ASP.NET MVC是如何运行的
    ASP.NET中后台注册js脚本攻略(转)
    Python: 什么是*args和**kwargs
    配置mysql 及 设置密码
    java静态方法Static
    并发程序设计知识总结
  • 原文地址:https://www.cnblogs.com/wo-shi-zhen-de-cai/p/10122579.html
Copyright © 2020-2023  润新知