问题背景 |
本套模拟题旨在复习各个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 }
时间: 2024-10-12 16:59:05