首页 > 代码库 > NOIp模拟1 Graph

NOIp模拟1 Graph

 

问题背景

本套模拟题旨在复习各个noip知识点

试题描述

给出 N 个点,M 条边的有向图,对于每个点 v,求 A(v) 表示从点 v 出发,能到达的编号最大的点。

输入格式

第 1 行,2 个整数 N,M。 接下来 M 行,每行 2 个整数 Ui,Vi,表示边 <Ui,Vi>。点用 1,2,...,N 编号。

输出格式

N 个整数 A(1),A(2),...,A(N)。

输入示例

4 3
1 2
2 4
4 3

输出示例

4 4 3 4

注释说明

对于 60% 的数据,1 ≤ N,K ≤ 10^3
对于 100% 的数据,1 ≤ N,M ≤ 10^5。

 

【分析】

这道题的做法应该比较多,这里选择记忆化dfs, 还没试能不能过,先放在这。

注意一个点要是不和其它任意点连通的话,a[i]就是它本身。

 

【代码】

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 struct State {
 5     int next, to;
 6 }e[200005];
 7 
 8 int n, m, u, v, head[100005], cnt, a[100005];
 9 bool vis[100005];
10 
11 void add(int u, int v) {
12     e[++cnt].to=v, e[cnt].next=head[u], head[u]=cnt;
13 }
14 
15 void dfs(int s) {
16     if (vis[s])
17         return;
18     vis[s]=true;
19     for (int i=head[s];i!=-1;i=e[i].next) {
20         dfs(e[i].to);
21         a[s]=max(a[s], max(e[i].to, a[e[i].to]));
22     }
23     return;
24 }
25 
26 int main() {
27     memset(head, -1, sizeof(head));
28     cin >> n >> m;
29     for (int i=1;i<=n;++i)
30         a[i]=i;
31     for (int i=1;i<=m;++i) {
32         scanf("%d %d", &u, &v);
33         add(u, v);
34     }
35     for (int i=1;i<=n;++i)
36         dfs(i);
37     for (int i=1;i<=n;++i)
38         printf("%d ", a[i]);
39 }

 

NOIp模拟1 Graph