POJ 2672 Tarjan + 缩点 + 拓扑思想

Going from u to v or from v to u?

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 17383   Accepted: 4660

Description

In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of their little sons go from one to the other. The son can either go from x to y, or from y to x. Wind promised that her tasks are all possible, but she actually doesn‘t know how to decide if a task is possible. To make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. Given a cave, can you tell Jiajia whether Wind can randomly choose two rooms without worrying about anything?

Input

The first line contains a single integer T, the number of test cases. And followed T cases.

The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly.

Output

The output should contain T lines. Write ‘Yes‘ if the cave has the property stated above, or ‘No‘ otherwise.

Sample Input

1
3 3
1 2
2 3
3 1

Sample Output

Yes

来源: http://poj.org/problem?id=2762


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

#include<cstdio>

#include<cstring>

#include<iostream>

#include<string>

#include<vector>

#include<stack>

#include<set>

#include<algorithm>

using namespace std;

#define N 1002

vector<int>Gra[N];

stack<int>Sta;

int map[N][N];

int dfn[N],low[N],inStack[N],belong[N],Time,cnt;

int inDegree[N];

void init()

{

    Time = cnt = 0;

    memset(dfn,0,sizeof(dfn));

    memset(low,0,sizeof(dfn));

    memset(inStack,0,sizeof(inStack));

    memset(inDegree,0,sizeof(inDegree));

    memset(belong,0,sizeof(belong));

    for(int i=0;i<N;i++) Gra[i].clear();

    memset(map,0,sizeof(map));

    while(!Sta.empty()) Sta.pop();

}

void Tarjan(int s)

{

    dfn[s] = low[s] = ++Time;

    inStack[s] = 1;

    Sta.push(s);

    for(int i=0;i<Gra[s].size();i++)

    {

        int j = Gra[s][i];

        if(dfn[j] == 0){

            Tarjan(j);

            low[s] = min(low[s], low[j]);

        }

        else if(inStack[j] == 1){

            low[s] = min(low[s], dfn[j]);

        }

    }

    if(dfn[s] == low[s])

    {

        cnt ++;

        while(!Sta.empty()){

            int temp = Sta.top(); Sta.pop();

            inStack[temp] = 0;

            belong[temp] = cnt;

            if(temp == s) break;

        }

    }

    return;

}

void tsort()

{

    for(int k=0;k<cnt;k++){

        int fuck = 0,pos;

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

        {

            if(inDegree[i] == 0)

            {

                fuck ++;

                pos = i;

            }

        }

        if(fuck > 1){

            printf("No\n");

            return ;

        }

        inDegree[pos ] = -1;

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

        {

            if(map[pos][i] == 1)

                inDegree[i]--;

        }

    }

    printf("Yes\n");

}

int main()

{

    int noc;

    cin>>noc;

    while(noc--)

    {

        init();

        int n,m,x,y;

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

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

        {

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

            Gra[x].push_back(y);

        }

        for(int i=1;i<=n;i++) if(dfn[i] == 0) Tarjan(i);

        if(cnt == 1) {

            printf("Yes\n");

            continue;

        }

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

        {

            for(int j=0;j<Gra[i].size();j++)

            {

                int k = Gra[i][j];

                if(belong[i]!=belong[k]){

                    if(map[belong[i]][belong[k]] == 0){

                        map[belong[i]][belong[k]] = 1;

                        inDegree[belong[k]]++;

                    }

                }

            }

        }

        for(int i=1;i<=cnt;i++) printf("%d %d\n",i,inDegree[i]);

        tsort();

    }

}

来源: http://tool.oschina.net/highlight

时间: 2024-11-09 22:27:04

POJ 2672 Tarjan + 缩点 + 拓扑思想的相关文章

POJ 2762 tarjan缩点+拓扑

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14566   Accepted: 3846 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

UVA 11324.The Largest Clique tarjan缩点+拓扑dp

题目链接:https://vjudge.net/problem/UVA-11324 题意:求一个有向图中结点数最大的结点集,使得该结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相互可达也可以). 思路:同一个强联通分量中满足结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相互可达也可以).把强联通分量收缩点后得到scc图,让每个scc结点的权值等于他的结点数,则求scc图上权最大的路径.拓扑dp,也可以直接bfs,但是要建立一个新的起点,连接所有入度为0

[模板]tarjan缩点+拓扑排序

题目:给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 题目简述:先tarjan缩点,再从入度为零处进行一次拓扑排序,求最长路即可,话说拓扑排序求最长路真方便... 注意: 要明确拓扑的写法,要用栈写最优. 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define man 100010 4 inline i

[ZJOI2007]最大半连通子图 (Tarjan缩点,拓扑排序,DP)

题目链接 Solution 大概是个裸题. 可以考虑到,如果原图是一个有向无环图,那么其最大半联通子图就是最长的一条路. 于是直接 \(Tarjan\) 缩完点之后跑拓扑序 DP就好了. 同时由于是拓扑序DP,要去掉所有的重边. Code #include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=100008; struct sj{int to,next;}a[maxn*10]; ll mo

bzoj5017 [Snoi2017]炸弹 (线段树优化建图+)tarjan 缩点+拓扑排序

题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5017 题解 这个题目方法挺多的. 线段树优化建图 线段树优化建图的做法应该挺显然的,一个炸弹能够引爆的炸弹的显然应该是一个区间里面的,直接对这个区间进行线段树优化建图. 这样可以得到一个带环图,缩点以后这个炸弹能够炸到的炸弹就是从这个点能够走到的点. 但是这个不太好做,不过可以发现最终的炸弹也是一个区间,所以可以通过缩点后的 DAG 来求出左右端点. 时间复杂度 \(O(n\log n)\)

POJ 2762 tarjan缩点+并查集+度数

Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15494   Accepted: 4100 Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors

HDU 6165 FFF at Valentine(Tarjan缩点+拓扑排序)

FFF at Valentine Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 575    Accepted Submission(s): 281 Problem Description At Valentine's eve, Shylock and Lucar were enjoying their time as any oth

BZOJ 1512 [POI2006]Pro-Professor Szu Tarjan缩点+拓扑DP

题意: n个别墅以及一个主建筑楼,从每个别墅都有很多种不同方式走到主建筑楼,其中不同的定义是(每条边可以走多次,如果走边的顺序有一条不同即称两方式不同). 询问最多的不同方式是多少,以及有多少个别墅有这么多方式,按照顺序输出别墅编号. 如果最多不同方式超过了36500那么都视作zawsze 解析: 容易想到把边反向,问题转化成求从主建筑楼走向各个点的方案数. 对于一个强连通分量,显然我们可以看做是一个点,所以首先把图缩点. 缩点之后 我们设f[i]表示走到第i个点的方案数. 显然f[i]=∑f[

POJ 1236 tarjan缩点+度数

Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11441   Accepted: 4554 Description A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a li