看了y总视频,有个思路,自己建图去写了写,发现第九个测试点过不去,
#include<bits/stdc++.h>
using namespace std;
const int N=1200,M=251500*2;
int h[N],e[M],ne[M],f[M],idx;
int q[N],d[N],cur[N];
int n,m,S,T;
int a[N];
int g[N];
int bf[M];
void add(int a,int b,int c){
e[idx]=b ; ne[idx]=h[a]; f[idx]=c; h[a]=idx++;
e[idx]=a; ne[idx]=h[b]; f[idx]=0; h[b]=idx++;
}
bool bfs(){
int hh=0,tt=-1;
memset(d,-1,sizeof d);
q[++tt]=S;
d[S]=0; cur[S]=h[S];
while(hh<=tt){
int t=q[hh++];
for(int i=h[t];~i;i=ne[i]){
int j=e[i];
if(d[j]==-1&&f[i]){
d[j]=d[t]+1;
cur[j]=h[j];
if(j==T)return true;
q[++tt]=j;
}
}
}
return false;
}
int find(int u ,int limit){
if(u==T)return limit;
int flow=0;
for(int i=cur[u];~i&&flow<limit;i=ne[i]){
cur[u]=i;
int j=e[i];
if(d[j]==d[u]+1&&f[i]){
int t=find(j,min(f[i],limit-flow));
if(!t)d[j]=-1;
f[i]-=t; f[i^1]+=t; flow+=t;
}
}
return flow;
}
int dinic(){
int res=0; int flow=0;
while(bfs())while(flow=find(S,1e8))res+=flow;
return res;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
memset(h,-1,sizeof h);
S=0,T=2*n+1; int r=0;
for(int i=1;i<=n;i++){
g[i]=1;
for(int j=1;j<i;j++){
if(a[j]<=a[i])g[i]=max(g[i],g[j]+1);
}
for(int j=1;j<i;j++){
if(a[j]<=a[i]&&g[i]==g[j]+1)add(j+n,i,1);
}
r=max(r,g[i]);
}
for(int i=1;i<=n;i++){
if(g[i]==1)add(S,i,1);
else if(g[i]==r)add(i+n,T,1);
}
for(int i=1;i<=n;i++){
add(i,i+n,1);
}
if(r==1){
cout<<1<<endl;
cout<<n<<endl;
cout<<n<<endl;
return 0;
}
cout<<r<<endl;
//memcpy(bf,f,sizeof f);
int res=dinic();
cout<<res<<endl;
//memcpy(f,bf,sizeof f);
add(S,1,1e8);
add(1,1+n,1e8);
add(n,n+n,1e8);
if(g[n]==r){ ////关键
add(n*2,T,1e8);
}
/*for(int i=0;i<idx;i+=2){
int xx=e[i^1]; int yy=e[i];
if(xx==S&&yy==1)f[i]=1e8;
else if(xx==1&&yy==n+1)f[i]=1e8;
else if(xx==n&&yy==n+n)f[i]=1e8;
else if(xx==n+n&&yy==T)f[i]=1e8;
}*/
cout<<res+dinic()<<endl;
}
主要是求第三个值的修改方式不一样对吧,,
总结:将原图的 某条边的值由1改成INF 和 在之前的这条边存在的情况下再加一条 同样两个点之间的INF的边 是等效的
可这是建立在原图的这两个点之间有边的情况下,,
如果原图没有这两个点之间的边,你去加INF了,那就破坏了逻辑,,
具体见92行操作,
修改有风险,加边须谨慎
y总视频 是在哪里看的呀?