码迷,mamicode.com
首页 > 其他好文 > 详细

网络流24题之最长不下降子序列

时间:2018-01-31 22:16:32      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:bsp   printf   直接   nod   while   pac   严格   class   stdin   

对于第一问直接n^2dp计算

第二问建图跑网络流

第三问将起始与结尾流量开大

建边的时候要严格按照子序列求法建

By:大奕哥

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=10005;
 4 int head[N],d[N],f[N],a[N];
 5 int n,m,cnt=-1,s,t,sum;
 6 struct node{
 7     int to,nex,w;
 8 }e[1000005];
 9 void add(int x,int y,int w)
10 {
11     e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;e[cnt].w=w;
12     e[++cnt].to=x;e[cnt].nex=head[y];head[y]=cnt;e[cnt].w=0;
13 }
14 queue<int>q;
15 bool bfs(int x,int y)
16 {
17     memset(d,-1,sizeof(d));
18     d[x]=0;q.push(x);
19     while(!q.empty())
20     {
21         int x=q.front();q.pop();
22         for(int i=head[x];i!=-1;i=e[i].nex)
23         {
24             int y=e[i].to;
25             if(d[y]!=-1||!e[i].w)continue;
26             d[y]=d[x]+1;q.push(y);
27         }
28     }
29     return d[y]!=-1;
30 }
31 int dfs(int x,int w,int yy)
32 {
33     if(x==yy||!w)return w;
34     int s=0;
35     for(int i=head[x];i!=-1;i=e[i].nex)
36     {
37         int y=e[i].to;
38         if(!e[i].w||d[y]!=d[x]+1)continue;
39         int flow=dfs(y,min(w-s,e[i].w),yy);
40         if(!flow){
41             d[y]=-1;continue;
42         }
43         e[i].w-=flow;e[i^1].w+=flow;s+=flow;
44         if(s==w)return s;
45     }
46     return s;
47 }
48 int dinic()
49 {
50     int ans=0;
51     while(bfs(s,t))
52     {
53         ans+=dfs(s,1e9,t);
54     }
55     return ans;
56 }
57 int main()
58 {
59     
60     freopen("1.out","r",stdin);
61     freopen("my.out","w",stdout);
62     scanf("%d",&n);
63     memset(head,-1,sizeof(head));
64     for(int i=1;i<=n;++i)
65     {
66         scanf("%d",&a[i]);
67         add(i,i+n,1);
68     }
69     s=0,t=n+n+10;int ans=1;
70     for(int i=1;i<=n;++i)
71     {
72         f[i]=max(f[i],1);add(i,i+n,1);
73         for(int j=i+1;j<=n;++j)
74         if(a[j]>=a[i])
75         {
76             f[j]=max(f[j],f[i]+1);
77             ans=max(f[j],ans);
78         }
79     }int pre=ans;
80     for(int i=1;i<=n;++i)
81     for(int j=i+1;j<=n;++j)
82     if(f[j]==f[i]+1&&a[j]>=a[i])
83     add(i+n,j,1);
84     printf("%d\n",ans);
85     for(int i=1;i<=n;++i)
86     {if(f[i]==1)add(s,i,1);
87     if(f[i]==ans)add(i+n,t,1);}
88     ans=dinic();
89     printf("%d\n",ans);
90     add(s,1,1e9);add(1,n+1,1e9);
91     if(f[n]==pre)
92     add(n+n,t,1e9),add(n,n+n,1e9);
93     ans+=dinic();
94     printf("%d\n",ans);
95     return 0;
96 }

 

网络流24题之最长不下降子序列

标签:bsp   printf   直接   nod   while   pac   严格   class   stdin   

原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8394285.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!