这题有三种做法
488ms / 9.61MB / 0.68KB
不用讲,直接贴代码
#include<bits/stdc++.h>
using namespace std;
const int N=1002;
int n,m,i,j,a[N],d[N],ans,f[N],k,vi[N][N],c[N][N],l;
int dfs(int x){
if (f[x]) return f[x];
for (int i=1;i<=c[x][0];i++) f[x]=max(f[x],dfs(c[x][i]));
return ++f[x];
}
int main(){
scanf("%d%d",&n,&m);
for (i=1;i<=m;i++){
scanf("%d",&a[0]);
for (j=1;j<=a[0];j++) scanf("%d",&a[j]);
l=1;
for (j=a[1];j<a[a[0]];j++)
if (a[l]==j) l++;
else for (k=1;k<=a[0];k++)
if (!vi[a[k]][j]) c[a[k]][++c[a[k]][0]]=j,vi[a[k]][j]=1;
}
for (i=1;i<=n;i++) ans=max(ans,dfs(i));
printf("%d",ans);
}
244ms / 13.34MB / 0.69KB
原本要连 条边:
但是,如果在中间添加一个虚点,就可以变成 条边:
#include<bits/stdc++.h>
using namespace std;
int n,m,ans,a[2003],s,i,j,u,to[2003][2003],uans[2003],sto[2003];
void dfs(int u){
if (uans[u]) return;
for(int i=1;i<=to[u][0];i++){
if(!uans[to[u][i]]) dfs(to[u][i]);
uans[u]=max(uans[u],uans[to[u][i]]+1);
}
if(u>n) uans[u]--;
ans=max(ans,uans[u]);
}
int main(){
scanf("%d%d",&n,&m);
for (i=1;i<=m;i++){
scanf("%d",&s);
for (j=1;j<=s;j++) scanf("%d",&a[j]),sto[a[j]]=i,to[n+i][++to[n+i][0]]=a[j];
for (u=a[1]+1;u<a[s];u++)
if (sto[u]!=i) to[u][++to[u][0]]=n+i;
}
for (i=1;i<=n;i++)
if (!uans[i]) dfs(i);
printf("%d",++ans);
}
72ms / 7.75MB / 1.62KB
看起来还是第二种方法更优,但是实际很快
有这样一棵线段树,每个点都和父亲连边:
每加进一个区间,则把线段树上对应区间和那个点连起来,比如加 这个区间:
代码是参考这里的,老师给我们讲过,但我写不出
#include<bits/stdc++.h>
using namespace std;
const int N=1500;
int h[N<<3],n,m,i,st[N],in[N<<3],num[N],dis[N<<3],dep[N<<3],tot,tp,q[N<<5],he,ta,cnt,j,ans;
struct node{
int to,ne;
}e[N*700];
inline char gc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline int read(){
int x=0,fl=1;char ch=gc();
for (;ch<48||ch>57;ch=gc())if(ch=='-')fl=-1;
for (;48<=ch&&ch<=57;ch=gc())x=(x<<3)+(x<<1)+(ch^48);
return x*fl;
}
void add(int x,int y){
in[y]++;
e[++tot]=(node){y,h[x]};
h[x]=tot;
}
void build(int t,int l,int r){
tp=max(tp,t);
if (l==r){
num[l]=t;
dis[t]=1;
return;
}
int mid=l+r>>1;
add(t<<1,t);
build(t<<1,l,mid);
add(t<<1|1,t);
build(t<<1|1,mid+1,r);
}
void update(int t,int l,int r,int x,int y,int tmp){
if (x<=l && r<=y){
add(t,tmp);
return;
}
int mid=l+r>>1;
if (x<=mid) update(t<<1,l,mid,x,y,tmp);
if (mid<y) update(t<<1|1,mid+1,r,x,y,tmp);
}
void bfs(){
for (int i=1;i<=tp;i++)
if (!in[i]) q[ta++]=i,dep[i]=dis[i];
while (he<ta){
int u=q[he++];
for (int i=h[u],v;i;i=e[i].ne){
v=e[i].to;
dep[v]=max(dep[v],dep[u]+dis[v]);
if (!(--in[v])) q[ta++]=v;
}
}
}
int main(){
n=read();m=read();
build(1,1,n);
for (i=1;i<=m;i++){
cnt=read();tp++;
for (j=1;j<=cnt;j++) st[j]=read();
for (j=1;j<cnt;j++){
add(tp,num[st[j]]);
if (st[j]+1<=st[j+1]-1) update(1,1,n,st[j]+1,st[j+1]-1,tp);
}
add(tp,num[st[cnt]]);
}
bfs();
for (i=1;i<=n;i++) ans=max(ans,dep[num[i]]);
printf("%d",ans);
}