poj 2762
6599 ワード
http://poj.org/problem?id=2762 nの部屋をあげます.mの一方通行で、任意のxに対してyの道がありますか?それともyからxまでありますか?
考え方:まずタタジャンで縮めて、更にトポロジーで並べ替えて、もし1つの点を取り除いたことを発見したら、2つの入度が0の点が新たに増加して、できません.
テストデータを添付します.4 1、2、3、2、4ハイ.
4 3 1 2 3 2 2 2 4 No.
考え方:まずタタジャンで縮めて、更にトポロジーで並べ替えて、もし1つの点を取り除いたことを発見したら、2つの入度が0の点が新たに増加して、できません.
テストデータを添付します.4 1、2、3、2、4ハイ.
4 3 1 2 3 2 2 2 4 No.
#include
#include
#include
#include
#include
#include
#define maxn 1005
using namespace std;
vector<int>edge[maxn];
vector<int>Edge[maxn];
int DFN[maxn],LOW[maxn],belong[maxn];
int Stack[maxn];
bool Instack[maxn];
int Index,cnt,top;
bool vis[maxn];
int in[maxn];
void Tarjan(int u)
{
int v;
DFN[u]=LOW[u]=++Index;
Stack[++top]=u;
Instack[u]=true;
for(int i=0;iif(DFN[v]==0)
{
Tarjan(v);
LOW[u]=min(LOW[v],LOW[u]);
}
else if(Instack[v])
LOW[u]=min(LOW[u],DFN[v]);
}
if(DFN[u]==LOW[u])
{
cnt++;
do
{
v=Stack[top--];
Instack[v]=false;
belong[v]=cnt;
}
while(u!=v);
}
}
bool topo()
{
queue<int>q;
memset(vis,false,sizeof(vis));
int ans=0;
for(int i=1;i<=cnt;i++)
{
if(in[i]==0)
{
q.push(i);
ans++;
// cout<
}
}
if(ans>1)return false;
while(!q.empty())
{
ans=0;
int cur=q.front();q.pop();
for(int i=0;iint v=Edge[cur][i];
in[v]--;
if(in[v]==0&&!vis[v])
{
ans++;
q.push(v);
vis[v]=true;
}
}
//cout<
if(ans>1)return false;
}
return true;
}
void init(int n)
{
Index=top=cnt=0;
memset(DFN,0,sizeof(DFN));
for(int i=1;i<=n;i++)
{
edge[i].clear();
Edge[i].clear();
}
}
int main()
{
int t,n,m;
cin>>t;
while(t--)
{
cin>>n>>m;
init(n);
for(int i=0;iint a,b;
scanf("%d%d",&a,&b);
edge[a].push_back(b);
}
for(int i=1;i<=n;i++)
if(DFN[i]==0)
Tarjan(i);
memset(in,0,sizeof(in));
for(int u=1;u<=n;u++)
{
for(int j=0;jint v=edge[u][j];
if(belong[u]!=belong[v])
{
// cout<
Edge[belong[u]].push_back(belong[v]);
in[belong[v]]++;
}
}
}
topo()?puts("Yes"):puts("No");
}
}