p1543

 

 样例输入 Sample Input  
10 16
1 2
1 4
1 10
2 3
2 5
4 3
4 5
4 8
6 5
7 6
7 9
8 5
9 8
10 6
10 7
10 9
样例输出 Sample Output 
9

蛤省真的坑,这里跟风学长婊一下。

然后就还算简单吧,一个拓扑排序的事。

记录每个点的入度和出度,写一个栈,把入度为0的放进去。然后开始循环,取出一个点,更新这个点所连点的ans和入度,如果入度也变成0了就把该所连点放进栈里,然后把那个点扔掉。

栈空的时候循环结束,这时所有点都被更新了(吧)。我们需要的是刚开始出度为0且入度不为0的点,可以实现准备好……

反正这个题有点坑的,一次A不掉也没关系,多调试几次就好了。

using namespace std;
int i,f,tx,ty,t;
int n,m;
int tot,link[100010],out[100010],in[100010];
int ans[100010],sum;
bool flag[100010];
stack <int > a;
struct node 
{
    int x,y,next;
}o[200010];
void add(int x,int y)
{
    tot++;
    o[tot].x=x;
    o[tot].y=y;
    o[tot].next=link[x];
    link[x]=tot;
}
int main()
{
ios::sync_with_stdio(false);
//freopen("123.in","r",stdin);
//freopen("123.out","w",stdout);
    cin>>n>>m;
    for(i=1;i<=m;i++)
    {
        cin>>tx>>ty;
        add(tx,ty);
        in[ty]++;
        out[tx]++;
    }
    
    for(i=1;i<=n;i++)
    {
        if(!out[i]&&!in[i])
            flag[i]=1;
        if(!in[i])
        {
            a.push(i);
            ans[i]=1;
        }
    }
    while(!a.empty())
    {
        t=a.top();
        a.pop();
        for(int j=link[t];j!=0;j=o[j].next)
        {
            in[o[j].y]--;
            ans[o[j].y]+=ans[t];
            if(!in[o[j].y])
                a.push(o[j].y);
        }
    }
    for(i=1;i<=n;i++)
        if(!out[i]&&!flag[i])
            sum+=ans[i];
    cout<<sum;
}
原文地址:https://www.cnblogs.com/qywyt/p/9574554.html