原题:https://pintia.cn/problem-sets/15/problems/861
思路:
1.计算每个结点的入度数
2.入度数为0的结点表示无需依赖其他工程自己就可以完成,将这些结点入栈同时计数
3.当栈未空时,取出栈一结点,对与它有关的结点度数减一,如果又产生入度数为0的结点则入栈同时计数。直到堆栈为空。
4.如果计数结果和结点总数相等说明每一个任务都可以完成,输出1
#include<iostream>
#include<stack>
#define MAXSIZE 110
using namespace std;
int N;
int G[MAXSIZE][MAXSIZE];
int vis[MAXSIZE];
int cnt;
int count(int s)//计算入度
{
int n=0;
for(int i=1;i<=N;i++)
{
if(G[i][s])n++;
}
return n;
}
int main()
{
int i,j,k,x;
scanf("%d",&N);
for(i=1;i<=N;i++)
{
scanf("%d",&k);
for(j=0;j<k;j++)
{
scanf("%d",&x);
G[x][i]=1;
}
}
stack <int>q;
int cnt=0;
for(i=1;i<=N;i++)
{
if(!count(i))//对于入度数为0的点入栈同时计数
{
q.push(i);
vis[i]=1;
cnt++;
}
}
while(!q.empty())
{
int p=q.top();
q.pop();
for(i=1;i<=N;i++)
{
if(G[p][i])G[p][i]--;//如果有边就将入度数减一
}
for(i=1;i<=N;i++)
{
if(count(i)==0&&vis[i]==0)//对于新的入度数为0并且没有访问过的点入栈同时计数
{
q.push(i);
vis[i]=1;
cnt++;
}
}
}
if(cnt==N)
printf("1");
else
printf("0");
return 0;
}