SDUT 2140 图结构练习——判断给定图是否存在合法拓扑序列

    xiaoxiao2021-03-25  80

    图结构练习——判断给定图是否存在合法拓扑序列 Time Limit: 1000MS Memory Limit: 65536KB Problem Description

    给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。

    Input

    输入包含多组,每组格式如下。 第一行包含两个整数n,m,分别代表该有向图的顶点数和边数。(n<=10) 后面m行每行两个整数a b,表示从a到b有一条有向边。

    Output

    若给定有向图存在合法拓扑序列,则输出YES;否则输出NO。

    Example Input

    1 0 2 2 1 2 2 1

    Example Output

    YES

    代码:

    #include<stdio.h> #include<string.h> int map[15][15]; int vis[15];/*标记入度*/ int flag; void tuopsort(int n) { int i, j, k; for(i = 1; i <= n; i++) { for(j = 1; j <= n; j++) { if(vis[j] == 0)//从小到大找,第一个入度为0的 { vis[j]--;//此时为-1,相当于删除的意思 k = j;//记录该城市编号 break; } } if(j == n+1)//如果满足代表没有找到,标记一下退出循环 { flag = 1; break; } for(j = 1; j <= n; j++) { if(map[k][j] == 1)//k->j如果存在道路,让其入度减1,因为之前变成-1,相当于没有了 { map[k][j] = 0;//因为k没有了,所以k->j的道路也就没有了 vis[j]--;//入度减1 } } } } int main() { int n, m, u, v; while(~scanf("%d %d", &n, &m)) { flag = 0; memset(map, 0, sizeof(map)); memset(vis, 0, sizeof(vis)); while(m--) { scanf("%d %d", &u, &v); map[u][v] = 1;//标记该路连通u->v vis[v]++;//入度++ } tuopsort(n);//拓扑排序 if(!flag) { printf("YES\n"); } else printf("NO\n"); } return 0; }

    另外一种方法:前向星

    #include<bits/stdc++.h> using namespace std; struct node { int to, next; }; node Map[1000]; int head[15]; int ru[15]; int q[15], n; void tp() { int cnt = 0, i; for(i = 1; i <= n; i++)//遍历一遍n找出(入度为0的点)入队列 { if(ru[i] == 0) q[cnt++] = i; } for(i = 0; i < cnt; i++)//遍历m条边 so 时间复杂度O(n + m) { int u = q[i]; for(int j = head[u]; ~j; j = Map[j].next) { int to = Map[j].to; ru[to]--;//入度-- if(!ru[to])//如果为0, 入队列 q[cnt++] = to; } } if(cnt == n) printf("YES\n"); else printf("NO\n"); } int main() { int m, u, v; while(~scanf("%d %d", &n, &m)) { memset(head, -1, sizeof(head)); memset(ru, 0, sizeof(ru)); int cnt = 0; while(m--) { scanf("%d %d", &u, &v); ru[v]++;//入度++ Map[cnt].to = v;//前向星建图 Map[cnt].next = head[u]; head[u] = cnt++; } tp(); } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-23734.html

    最新回复(0)