洛谷P1137旅行计划
 
思路:
 
题目说只能走到东边的城市,又保证
    
     
      
       
        x
       
      
      
       x
      
     
    x再
    
     
      
       
        y
       
      
      
       y
      
     
    y的西面,虽然说是双向道路,但是就可以直接建
    
     
      
       
        (
       
       
        x
       
       
        ,
       
       
        y
       
       
        )
       
      
      
       (x,y)
      
     
    (x,y)的边。 可以得到
    
     
      
       
        d
       
       
        p
       
       
        [
       
       
        v
       
       
        ]
       
       
        =
       
       
        max
       
       
        
       
       
        (
       
       
        d
       
       
        p
       
       
        [
       
       
        v
       
       
        ]
       
       
        ,
       
       
        d
       
       
        p
       
       
        [
       
       
        u
       
       
        ]
       
       
        +
       
       
        1
       
       
        )
       
      
      
       dp[v]=\max(dp[v],dp[u]+1)
      
     
    dp[v]=max(dp[v],dp[u]+1),那么怎么解决后效性呢?就是用拓扑排序,因为拓扑排序出来的点就可以保证一个点不会再有入度,这样就不会受到别的点的影响,这样就没有了后效性。
 
代码:
 
#include<bits/stdc++.h>
#define pii pair<int,int>
#define ll long long
#define cl(x,y) memset(x,y,sizeof(x))
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define lson x<<1,l,mid
#define rson x<<1|1,mid+1,r
#define INF 1e18
const int N
=1e6+10;
const int mod
=1e9+7;
const int inf
=0x3f3f3f3f;
const double eps
=1e-8;
const double pi
=acos(-1);
using namespace std
;
struct edge
{
	int u
,v
;
}e
[N
];
int head
[N
]={0},len
=0,in
[N
]={0},dp
[N
]={0};
void add(int u
,int v
)
{
	e
[++len
]={head
[u
],v
};
	head
[u
]=len
;
}
int main()
{
	ios
::sync_with_stdio(false);
	cin
.tie(0);cout
.tie(0);
	int n
,m
,i
;
	cin
>>n
>>m
;
	for(i
=1;i
<=m
;i
++)
	{
		int u
,v
;
		cin
>>u
>>v
;
		add(u
,v
);
		in
[v
]++;
	}
	queue
<int> q
;
	for(i
=1;i
<=n
;i
++)
		if(!in
[i
])
			q
.push(i
);
	while(!q
.empty())
	{
		int u
=q
.front();
		q
.pop();
		for(i
=head
[u
];i
;i
=e
[i
].u
)
		{
			int v
=e
[i
].v
;
			dp
[v
]=max(dp
[u
]+1,dp
[v
]);
			in
[v
]--;
			if(!in
[v
])
				q
.push(v
);
		}
	}
	for(i
=1;i
<=n
;i
++)
		cout
<<dp
[i
]+1<<endl
;
	return 0;
}