原题链接:http://poj.org/problem?id=2762
题意:给出一些点,和他们之间的有向边,如果图中任意两点 x,y 之间满足 x 可以到达 y 或者 y 可以到达 x ,就输出“Yes”,否则输出“No”,注意,这里是 x 到达 y ,或者 y 到达 x ,是 或者 不是 而且 !!!
分析:先缩点建一个新图,然后拓扑排序,看入度为0的点个数,点个数大于1,就是No。
还有为什么我注释的代码会报错呢?想不通。。。。。。
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<vector>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#define INF 99999999
using namespace std;
int t;
int n, m;
int cnt;
int index;
vector<int> g[1005];
vector<int> gg[1005];
stack<int> s;
int dfn[1005];
int low[1005];
int belong[1005];
int in[1005];
bool inStack[1005];
void trajan(int u)
{
dfn[u] = low[u] = ++index;
inStack[u] = 1;
s.push(u);
for (int i = 0; i < g[u].size(); i++)
{
int v = g[u][i];
if (!dfn[v])
{
trajan(v);
low[u] = min(low[u], low[v]);
}
else if (inStack[v])
low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u])
{
cnt++;
int temp;
do
{
temp = s.top();
s.pop();
inStack[temp] = 0;
belong[temp] = cnt;
} while (temp != u);
}
}
void solve()
{
cnt = index = 0;
memset(dfn, 0, sizeof(dfn));
for (int i = 1; i <= n; i++)
if (!dfn[i])
trajan(i);
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < g[i].size(); j++)
{
int w = g[i][j];
if (belong[i] != belong[w])
{
gg[belong[i]].push_back(belong[w]);
in[belong[w]]++;
}
}
}
}
void topo()
{
int num = 0;
int p;
queue<int> q;
for (int i = 1; i <= cnt; i++)
{
if (in[i] == 0)
{
num++;
q.push(i);
}
}
if (num > 1)
{
printf("No\n");
return;
}
while(!q.empty())
{
p = q.front();
q.pop();
num = 0;
for (int j = 0; j < gg[p].size(); j++)
{
in[gg[p][j]]--;
if (in[gg[p][j]] == 0)
{
num++;
q.push(gg[p][j]);
}
if (num > 1)
{
printf("No\n");
return;
}
}
}
//for (int i = 1; i <= cnt; i++)
//{
// num = 0;
// for (int j = 0; j < gg[p].size(); j++)
// {
// in[gg[p][j]]--;
// if (in[gg[p][j]] == 0)
// {
// num++;
// p = gg[p][j];
// }
// if (num > 1)
// {
// printf("No\n");
// return;
// }
// }
//}
printf("Yes\n");
}
int main()
{
int u, v;
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &m);
//init
while (!s.empty())
s.pop();
for (int i = 1; i <= n; i++)
{
g[i].clear();
gg[i].clear();
in[i] = 0;
inStack[i] = 0;
}
for (int i = 0; i < m; i++)
{
scanf("%d%d", &u, &v);
g[u].push_back(v);
}
solve();
topo();
}
return 0;
}