http://acm.hdu.edu.cn/showproblem.php?pid=1269
题意:中文题。。
思路:Tarjan算法,赤果果的强连通分量,直接上模板
#include <stack>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 10005;
stack<int> sta;
vector<int> side[100005];
int time, sum;
int low[maxn], dfn[maxn];
bool instack[maxn], vis[maxn];
int Tarjan(int rt)
{
sta.push(rt);
vis[rt] = true;
instack[rt] = true;
low[rt] = dfn[rt] = ++time;
int len = side[rt].size();
for(int i = 0; i < len; i++)
{
int rw = side[rt][i];
if(!vis[rw]){
Tarjan(rw);
low[rt] = min(low[rt], low[rw]);
}
else if(instack[rw]){
low[rt] = min(low[rt], dfn[rw]);
}
}
if(low[rt] == dfn[rt]){
int top;
do{
top =sta.top();
sta.pop();
instack[top] = false;
}while(top != rt);
sum++;
}
return 0;
}
int main()
{
int n, m;
while(~scanf("%d%d", &n, &m) && (n || m)){
for(int i = 0; i <= n; i++){
side[i].clear();
}
int x, y;
for(int i = 0; i < m; i++){
scanf("%d%d", &x, &y);
side[x].push_back(y);
}
sum = time = 0;
memset(low, 0, sizeof(low));
memset(dfn, 0, sizeof(dfn));
memset(vis, false, sizeof(vis));
memset(instack, false, sizeof(instack));
for(int i = 1; i <= n; i++){
if(!dfn[i])
Tarjan(1);
}
if(sum == 1){
printf("Yes\n");
}
else{
printf("No\n");
}
}
}