Datahub
数据改变生活

发表时间:2022-10-27 20:37

描述

一个数列 a 称为合法的当且仅对于所有的位置 i, j(i < j ≤ n),都不存在一条从 aj 点连向 ai 的有向边。现在有很多个有向无环图,请你判断每个图是否只存在唯一的合法数 列。

输入

输入的第一行包含一个正整数 T ,表示数据组数。

对于每组数据,第一行包含两个正整数 n, m,表示图的节点个数和边数。

接下来 m 行,每行包含两个正整数 x, y(x, y ≤ n),表示这个图有一条从 x 到 y 的有向边。

保证没有自环和重边。

输出 T 行,若所给的图存在唯一的合法数列,输出 1,否则输出 0。

样例 1 输入

2

32

12

23

32

12

13

样例 1 输

样例 1 解释

第一个图只有一个合法数列:1、2、3;

第二个图有两个合法数列:1、2、3 或者 1、3、2。

样例 2

请查看下发文件内的 sample2_input.txt 和 sample2_output.txt。

限制

对于 50%的数据,n, m ≤ 100;

对于 100%的数据,T ≤ 100, n, m ≤ 10000。时间:4 sec

空间:512 MB

提示

[本题就是判断一个有向无环图是否存在唯一的拓扑序列。]

[回忆一下求拓扑序列是如何做的:每一次都取一个入度为 0 的点,将这个点取出来放进拓扑序列里,然后将这个点连向的所有点的入度减去 1。]

[可以发现,在“每一次都取一个入度为 0”这一步,若入度为 0 的点数多于 1 个,则显然拓扑序不唯一。]

[因此按照这个拓扑序算法做一遍就好。]

代码

#include <bits/stdc++.h> using namespace std; #include <bits/stdc++.h> using namespace std;

// ================= 代码实现开始 =================

const int N = 10005;

// 为了减少复制开销,我们直接读入信息到全局变量中,并统计了每个点的入度到数组in中

// n, m:点数和边数

// in:in[i]表示点i的入度

// e:e[i][j]表示点i的第j条边指向的点int n, m, in[N];

vector<int> e[N];

// 判断所给有向无环图是否存在唯一的合法数列

// 返回值:若存在返回1;否则返回0。bool getAnswer() {

//找到一个入度为0的点。有向无环图中至少存在一个入度为0的点

//若存在多个入度为0的点,说明合法序列不唯一

int x = 0;

for (int i = 1; i <= n; ++i)

if (in[i] == 0) {

if (x != 0)//表示入度为0的点不唯一

return 0;

x = i;

}

//x表示的就是图中唯一的入度为0的点,然后去除关联的边

for (int j = 1; j <= n; ++j) {

int z = 0;

for (int i = 0; i < (int)e[x].size(); ++i) {

int y = e[x][i];

--in[y];

if (in[y] == 0) {

if (z != 0)

return 0;

z = y;

}

}

x = z;

}

return 1;

}

// ================= 代码实现结束 =================

int main() {

    int T;

    for (scanf("%d", &T); T--; ) {

        scanf("%d%d", &n, &m);

        for (int i = 1; i <= n; ++i) {

            in[i] = 0;

            e[i].clear();

        }

        for (int i = 0; i < m; ++i) {

            int x, y;

            scanf("%d%d", &x, &y);

            e[x].push_back(y);

            ++in[y];

        }

        printf("%d\n", getAnswer());

    }

    return 0;

}


上一篇最近点对
下一篇凸包
文章分类: 数据结构例题
分享到:
QQ:258506508                                     联系电话:020-000000    000-000000                                   联系邮箱:xxx@.co.m                                     联系地址:XXX省XXX市XXX县XXX路