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; }