题意:
给你n个点m条边。入度为0的点标为1,如果一个点只有一个点指向,那么它标为那个点的标数。如果一个点有两个或以上相同标号的点指向。那么给它标为i+1,如果有更大的话就标为更大的。求最大的标号。
解析:
这题可以借鉴宽度优先搜索拓扑排序的思想,但是这边有一个技巧,用vis[]数组来表示当前节点是否有两个入度,如果有当前节点上有两个入度的话,就将vis[]标记为true。
每次bfs时,就将当前点的 order[u] += vis[u];
AC代码
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int N = 1e3 + 10;
int n, m, indeg[N], order[N];
bool vis[N];
vector<int> g[N];
void init() {
memset(vis, 0, sizeof(vis));
memset(indeg, 0, sizeof(indeg));
memset(order, 0, sizeof(order));
for(int i = 0; i < N; i++) {
g[i].clear();
}
}
void add(int from, int to) {
g[from].push_back(to);
}
int bfs() {
queue<int> que;
for(int i = 1; i <= n; i++) {
if(indeg[i] == 0) {
order[i] = 1;
que.push(i);
}
}
while(!que.empty()) {
int u = que.front();
que.pop();
order[u] += vis[u];
for(int i = 0; i < g[u].size(); i++) {
int v = g[u][i];
indeg[v]--;
if(order[v] < order[u]) {
order[v] = order[u];
vis[v] = false;
}else if(order[v] == order[u]) {
vis[v] = true;
}
if(indeg[v] == 0)
que.push(v);
}
}
return order[n];
}
int main() {
int T, cas;
scanf("%d", &T);
while(T--) {
init();
scanf("%d%d%d", &cas, &n, &m);
int u, v;
while(m--) {
scanf("%d%d", &u, &v);
add(u, v);
indeg[v]++;
}
printf("%d %d\n", cas, bfs());
}
return 0;
}
UVALive 6467:拓扑排序解决Strahler Order问题
该博客介绍了如何利用拓扑排序解决UVALive 6467题目的Strahler Order问题。通过理解题目要求,即根据点的入度给点分配标号,并确保标号符合特定规则,博主提出利用宽度优先搜索(BFS)策略。在BFS过程中,使用vis[]数组记录节点是否存在两个入度的情况,从而更新节点的标号。最后,博主提供了AC代码来展示解决方案。
517

被折叠的 条评论
为什么被折叠?



