您的位置:首页 > 其它

Ural(Timus) 1078. Segments

2013-02-05 12:08 591 查看
DP(DAG最长路)

题意:给出x轴上的线段的端点坐标,一个线段能覆盖另一个线段(端点不能相同),求出最多的线段覆盖并且从短到长给出路径。转化模型为DAG,求DAG上的最长路并且打印路径,用记忆化搜索实现

#include <cstdio>
#include <cstring>
#define N 550
int a
,b
,n;
bool g

;
int dp
,path
;

void dfs(int i)
{
if(dp[i]!=-1) return ;

dp[i]=1;
for(int j=1; j<=n; j++) if(g[i][j])
{
dfs(j);
if( dp[j]+1 > dp[i] )
{ dp[i]=dp[j]+1; path[i]=j; }
}
return ;
}

int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1; i<=n; i++) scanf("%d%d",&a[i],&b[i]);
memset(g,0,sizeof(g));
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(a[i]<a[j] && b[j]<b[i]) //i能包含j
g[i][j]=1;

memset(dp,-1,sizeof(dp));
memset(path,-1,sizeof(path));

int max=0,m=0;
for(int i=1; i<=n; i++) //枚举所有点求出最长路
{
if(dp[i]==-1)
{
dp[i]=1;
for(int j=1; j<=n; j++) if(g[i][j]) //i能包含j
{
dfs(j);
if(dp[j]+1 > dp[i])
{ dp[i]=dp[j]+1; path[i]=j; }
}
}
if( dp[i]>max )
{ max=dp[i]; m=i;}
}

int s
,top=0;
printf("%d\n",max);
while(m!=-1)
{ s[top++]=m; m=path[m]; }
for(int i=top-1; i>=0; i--)
if(i) printf("%d ",s[i]);
else  printf("%d\n",s[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: