传送门biu~
第一个问题,对于导弹a严格小于导弹b,我们可以连一条a->b的边,对于整个图来说,因为边表示的关系是大小关系,所以这个图一定是个拓扑图,只要拓扑排序递推求最长链就可以了。
第二个问题,同样像上一个问题那样连边,求最小路径覆盖。
#include <bits/stdc++.h>
#define S 0
#define T 2001
#define INF 1000000000
using namespace std;
int n;
//task1:
struct dd{
int x,y,z;
bool operator<(const dd &r){return (x<r.x && y<r.y && z<r.z);}
}a[1005];
int head1[1005],in1[1005],nex1[1000005],to1[1000005],tp1=0;
queue<int>q;int len[1005];
inline void add(int x,int y){
nex1[++tp1]=head1[x];
head1[x]=tp1;
to1[tp1]=y;
++in1[y];
}
inline int topo(){
int ans=0;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=head1[x];i;i=nex1[i]){
len[to1[i]]=max(len[to1[i]],len[x]+1);
if(!--in1[to1[i]]) q.push(to1[i]);
}
ans=max(ans,len[x]);
}
return ans;
}
inline void solve1(){
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(a[i]<a[j]) add(i,j);
for(int i=1;i<=n;++i) if(!in1[i]) q.push(i),len[i]=1;
printf("%d\n",topo());
}
//task2:
int head2[2005],nex2[2000005],to2[2000005],cap2[2000005],tp2=1;
int dep[2005],fir[2005];
inline void add2(int x,int y){
nex2[++tp2]=head2[x];
head2[x]=tp2;
to2[tp2]=y;
cap2[tp2]=1;
nex2[++tp2]=head2[y];
head2[y]=tp2;
to2[tp2]=x;
cap2[tp2]=0;
}
int dfs(int x,int now)
{
if(!now || x==T) return now;
int c=0;
for(int &i=fir[x];i;i=nex2[i])
{
if(cap2[i] && dep[to2[i]]==dep[x]+1)
{
int f=dfs(to2[i],min(now,cap2[i]));
c+=f;
now-=f;
cap2[i]-=f;
cap2[i^1]+=f;
if(!now) break;
}
}
return c;
}
inline bool bfs()
{
memset(dep,0,sizeof(dep));
dep[S]=1;
queue<int>q;
q.push(S);
while(!q.empty())
{
int x=q.front(); q.pop();
for(int i=head2[x];i;i=nex2[i])
{
if(cap2[i]&&!dep[to2[i]])
{
dep[to2[i]]=dep[x]+1;
q.push(to2[i]);
}
}
}
return dep[T];
}
inline int Dinic(){
int c=0;
while(bfs()){
for(int i=1;i<=2*n;++i) fir[i]=head2[i];
fir[S]=head2[S]; fir[T]=head2[T];
c+=dfs(S,INF);
}
return c;
}
inline void solve2(){
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(a[i]<a[j]) add2(i,n+j);
for(int i=1;i<=n;++i) add2(S,i);
for(int i=n+1;i<=2*n;++i) add2(i,T);
printf("%d",n-Dinic());
}
inline void init(){
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
}
int main(){
init();
solve1();
solve2();
return 0;
}