/*SE:wn------王宁*/
我加了一些注释——划重点+帮助思考。
源代码出处:https://blog.csdn.net/qq_36300700/article/details/78397748
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
const int maxn=1000+5;
int G[maxn][maxn],d[maxn],n,b[maxn],sum=0,path[maxn];
//b数组保存起点,sum表示起点有多少个
int dp(int i)
{
int& ans = d[i];
if(ans > 0)
return ans;
ans =1;
for(int j = 1; j <= n; j++)
if(G[i][j])
ans = max(ans, dp(j)+1);
return ans;
}
void print_ans(int i,int k)
{
/*这就是打印出所有路径的后半部分答案——路径的完整性*/
path[k]=i;
if(d[i]==1)
{
for(int i=0;i<=k;i++)
printf("%d ",path[i]);
printf("\n");
return ;
}
for(int j = 1; j <=n; j++)
if(G[i][j]&&d[i]==d[j]+1)
{
print_ans(j,k+1);
}
}
int main()
{
// freopen("in.txt","r",stdin);
memset(G,0,sizeof(G));
memset(d,0,sizeof(d));
int x[maxn],y[maxn],t,max_sum=0,sub;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d %d",&x[i],&y[i]);
/*优秀的处理方法:分出长和宽,如果xi<xj,yi>yj,那么再比较if(yi<xj&&xi<yj)
是没有意义的,因为yj<yi<xi<xj*/
if(x[i]<y[i])
{
t=x[i];
x[i]=y[i];
y[i]=t;
}
}
/*邻接矩阵处理点与点之间的关系*/
for(int i=1; i<=n; i++)
//因为前面的点已经和它在之前比较过了,所以j从i+1开始
for(int j=i+1; j<=n; j++)
{
if(x[i]>x[j]&&y[i]>y[j])
G[i][j]=1;
else if(x[i]<x[j]&&y[i]<y[j])
G[j][i]=1;
}
/*对于已经遍历过的点不用重新求值了,所以不用将d数组清零——之前想的一个误区*/
for(int i=1; i<=n; i++)
dp(i);
for(int i=1; i<=n; i++)
{
if(d[i]>max_sum)
{
max_sum=d[i];
sub=i;
}
}
/*这就是打印出所有路径的前半部分答案——起点的完整性*/
for(int i=1; i<=n; i++)
{
if(d[i]==max_sum)
b[++sum]=i;
}
for(int i=1;i<=sum;i++)
print_ans(b[i],0);
return 0;
}