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?
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
Sample Output
解题思路:缩点后判断是不是一条链即可,一条链直接判断入度和出度就好了
#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;
}
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 18552 | Accepted: 4997 |
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;
}
相关文章推荐
- [练习][poj2762]tarjan缩点 Going from u to v or from v to u?
- POJ 2762 Going from u to v or from v to u? Tarjan缩点+判断链
- POJ2762 Going from u to v or from v to u? 强连通 Tarjan缩点+拓扑排序topsort
- poj 2762 Going from u to v or from v to u? 【判断图是否为弱连通】 【tarjan求SCC + 缩点 + 拓扑排序】
- poj 2762 Going from u to v or from v to u?(缩点+拓扑排序)
- [ tarjan + dfs ] poj 2762 Going from u to v or from v to u?
- POJ 2762【强联通缩点】【拓扑排序】Going from u to v or from v to u?
- POJ 2762 Going from u to v or ... 弱连通图 tarjan
- POJ 2762 Going from u to v or ... 弱连通图 tarjan
- poj 2762 Going from u to v or from v to u?(强连通、缩点、拓扑)
- poj2762 Going from u to v or from v to u? --- 缩点+拓扑
- Going from u to v or from v to u? - POJ 2762 Tarjan+拓扑排序
- [ tarjan + dfs ] poj 2762 Going from u to v or from v to u?
- POJ 2762 Going from u to v or from v to u? (图论-tarjan)
- POJ-2762 Going from u to v or from v to u? (强连通分量[Tarjan]&&(拓扑排序||树形DP))
- POJ 2762 Going from u to v or from v to u? (图论-tarjan)
- POJ 2762 Going from u to v or from v to u? (Tarjan) - from lanshui_Yang
- POJ 2762 Going from u to v or from v to u? (Tarjan) - from lanshui_Yang
- poj 2762 Going from u to v or v to u (tarjan+缩点+dfs搜索)
- POJ 2762 Going from u to v or from v to u?(Tarjan)