您的位置:首页 > 编程语言 > Go语言

POJ - 2762 Going from u to v or from v to u? (Tarjan 缩点)

2018-01-26 17:30 661 查看
Going from u to v or from v to u?

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 18552 Accepted: 4997
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


解题思路:缩点后判断是不是一条链即可,一条链直接判断入度和出度就好了

#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <memory.h>
#include <bitset>
#include <map>
#include <deque>
#include <math.h>
#include <stdio.h>
using namespace std;
using namespace std;

typedef long long int ll;

const int MAXN = 300005;

vector<int> G[1005];
int N, M;
int color[1005];
int dfn[1005];
int low[1005];
int vis[1005];
int instack[1005];
int sta[1005];
int cnt = 0;
int vistime = 1;
int col = 1;

int indegree[1005];
int outdegree[1005];

void init()
{

for (int i = 0; i < 1005; i++)
G[i].clear();
memset(color, 0, sizeof(color));
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(vis, 0, sizeof(vis));
memset(instack, 0, sizeof(instack));
memset(sta, 0, sizeof(sta));
memset(indegree, 0, sizeof(indegree));
memset(outdegree, 0, sizeof(outdegree));
cnt = 0;
vistime = 1;
col = 1;
}

void tarjan(int v1)
{
dfn[v1] = low[v1] = vistime;
vistime++;

vis[v1] = 1;

sta[cnt++] = v1;
instack[v1] = 1;

for (int i = 0; i < G[v1].size(); i++)
{
if (!vis[G[v1][i]])
{
tarjan(G[v1][i]);
low[v1] = min(low[v1], low[G[v1][i]]);
}
else if (instack[G[v1][i]])
low[v1] = min(low[v1], dfn[G[v1][i]]);
}
if (dfn[v1] == low[v1])
{
int temp;
do
{
temp = sta[--cnt];
color[temp] = col;//缩点
instack[temp] = 0;

} while (temp != v1);
col++;
}
}

void SD()
{
for (int i = 1; i <= N; i++)
{
for (int j = 0; j < G[i].size(); j++)
{
if (color[i] != color[G[i][j]])
{
outdegree[color[i]]++;
indegree[color[G[i][j]]]++;
}
}
}
}

int main()
{

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

init();
int temp;
scanf("%d%d", &N, &M);
for (int i = 1; i <= M; i++)
{
int a, b;
scanf("%d%d", &a, &b);
G[a].push_back(b);
}

for (int i = 1; i <= N; i++)
if (!vis[i])
tarjan(i);

SD();

int t1 = 0, t2 = 0, t3 = 0;
for (int i = 1; i < col; i++)
{
if (indegree[i] == 1 && outdegree[i] == 1)
t1++;
if (indegree[i] == 0 && outdegree[i] == 1)
t2++;
if (indegree[i] == 1 && outdegree[i] == 0)
t3++;
}

if ((t2 == 1 && t3 == 1 && t1 == (col - 3)) || col == 2)
printf("Yes\n");
else
printf("No\n");
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: