• 【网络流24题】 No.6 最长不减子序列问题 (最大流)[模型:最多不相交路径]


    【题意】  

    给定正整数序列x1 ,x2 , x3...

    ( 1)计算其最长不减子序列的长度 s。
    ( 2)计算从给定的序列中最多可取出多少个长度为 s 的不减子序列。
    ( 3) 如果允许在取出的序列中多次使用 x1 和 xn, 则从给定序列中最多可取出多少个长度为 s 的不减子序列。

    输入文件示例
    input.txt
    4
    3 6 2 5


    输出文件示例
    output.txt
    2
    2
    3

    【题意】

      数据比较小。

      首先算出LIS,(n^2都可以了)

      然后连边,这题点也有流量哦,所以要拆点。(一个点拆两个,一个负责进,一个负责出)

      st->u1 流量为1  (f[u]==mx) mx为第一问答案,f为求LIS的数组

         u2->ed 流量为1 (f[u]==1)

      每个点 u1->u2 流量为1

      对于 f[i]==f[j]+1 且a[i]>a[j] i>j : i2->j1 流量为1

      然后跑最大流就是第二问。

      对于第三问,实际上表示1和n是不用拆点的。

      在残量网络上加边 st->n 流量为INF (当f[n]==mx)

      1->ed 流量为INF

      1->1 INF   n1->n2 INF

      然后继续跑最大流,累加上第二问的答案就是第三问答案。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 #include<cmath>
      8 using namespace std;
      9 #define Maxn 1010
     10 #define INF 0xfffffff
     11 
     12 struct node
     13 {
     14     int x,y,f,o,next;
     15 }t[Maxn*1010];int len;
     16 int first[Maxn];
     17 
     18 int mymin(int x,int y) {return x<y?x:y;}
     19 int mymax(int x,int y) {return x>y?x:y;}
     20 
     21 void ins(int x,int y,int f)
     22 {
     23     t[++len].x=x;t[len].y=y;t[len].f=f;
     24     t[len].next=first[x];first[x]=len;t[len].o=len+1;
     25     t[++len].x=y;t[len].y=x;t[len].f=0;
     26     t[len].next=first[y];first[y]=len;t[len].o=len-1;
     27 }
     28 
     29 int st,ed;
     30 queue<int > q;
     31 int dis[Maxn];
     32 bool bfs()
     33 {
     34     while(!q.empty()) q.pop();
     35     memset(dis,-1,sizeof(dis));
     36     q.push(st);dis[st]=0;
     37     while(!q.empty())
     38     {
     39         int x=q.front();
     40         for(int i=first[x];i;i=t[i].next) if(t[i].f>0)
     41         {
     42             int y=t[i].y;
     43             if(dis[y]==-1)
     44             {
     45                 dis[y]=dis[x]+1;
     46                 q.push(y);
     47             }
     48         }
     49         q.pop();
     50     }
     51     if(dis[ed]==-1) return 0;
     52     return 1;
     53 }
     54 
     55 int ffind(int x,int flow)
     56 {
     57     if(x==ed) return flow;
     58     int now=0;
     59     for(int i=first[x];i;i=t[i].next) if(t[i].f>0)
     60     {
     61         int y=t[i].y;
     62         if(dis[y]==dis[x]+1)
     63         {
     64             int a=ffind(y,mymin(flow-now,t[i].f));
     65             t[i].f-=a;
     66             t[t[i].o].f+=a;
     67             now+=a;
     68         }
     69         if(now==flow) break;
     70     }
     71     if(now==0) dis[x]=-1;
     72     return now;
     73 }
     74 
     75 void output()
     76 {
     77     for(int i=1;i<=len;i+=2)
     78      printf("%d->%d %d
    ",t[i].x,t[i].y,t[i].f);
     79 }
     80 
     81 int max_flow()
     82 {
     83     int ans=0;
     84     while(bfs())
     85     {
     86         ans+=ffind(st,INF);
     87         // printf("--%d
    ",ans);
     88         // output();
     89     }
     90     return ans;
     91 }
     92 
     93 int n,ans=0;
     94 int a[Maxn],f[Maxn];
     95 
     96 void init()
     97 {
     98     scanf("%d",&n);
     99     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    100     for(int i=1;i<=n;i++)
    101     {
    102         f[i]=1;
    103         for(int j=1;j<i;j++) if(a[i]>=a[j])
    104           f[i]=mymax(f[i],f[j]+1);
    105         ans=mymax(ans,f[i]);
    106     }
    107     printf("%d
    ",ans);
    108 }
    109 
    110 int main()
    111 {
    112     init();
    113     len=0;
    114     memset(first,0,sizeof(first));
    115     st=n*2+1;ed=st+1;
    116     for(int i=1;i<=n;i++) ins(i,i+n,1);
    117     for(int i=1;i<=n;i++) if(f[i]==1) ins(i+n,ed,1);
    118     for(int i=1;i<=n;i++) if(f[i]==ans) ins(st,i,1);
    119     for(int i=1;i<=n;i++)
    120      for(int j=i+1;j<=n;j++) if(f[j]==f[i]+1&&a[j]>=a[i]) ins(j+n,i,1);
    121     int x=max_flow();
    122     printf("%d
    ",x);
    123     
    124     if(f[n]==ans) ins(st,n,INF);
    125     ins(1+n,ed,INF);ins(1,1+n,INF);ins(n,n+n,INF);
    126     x+=max_flow();
    127     printf("%d
    ",x);
    128     return 0;
    129 }
    View Code

    2016-11-04 14:05:24

      

     

  • 相关阅读:
    UDP与TCP报文格式,字段意义
    TCP报文头部解析
    SQL中IN和EXISTS用法的区别
    SQL中EXISTS的用法
    rabbitmq之一概念解释(信道、交换器和路由键、队列)
    Memcache,Redis,MongoDB三种非关系型数据库的对比
    linux chage
    linux用户组管理
    c++ decltype
    c++ 隐式转换(explicit与转换构造函数)
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6030037.html
Copyright © 2020-2023  润新知