/*用队列是因为
一层层(每次选一层度为0的,其实也是按钱的档次分的)
处理更高效。可避免重复多余的操作 ??
*///领接矩阵内存超限,所以要用领接表 #include<bits/stdc++.h> using namespace std; const int maxn=1e4+5; typedef long long ll; int n,m,ind[maxn],res[maxn]; vector <int> g[maxn]; int topu(){ queue<int> q; int u,cnt=0,ans=0; for(int j=1;j<=n;j++){ if(!ind[j]){ ind[j]--;//每次找点,所以用过的度为0的点要删去,而边可不用操作 q.push(j); } } while(!q.empty()){ u=q.front(),q.pop(); ans+=res[u];//写在pop这儿可以保证每个点都加到(不会漏掉 值不为0的u) cnt++;//记录度为0的点 for(int j=0;j<g[u].size();j++){ int v=g[u][j]; ind[v]--; /*u相连的点v中,度为0的v才+1.才能保证最小 因为它要比所有入它的点都大,所以若入度不为0,说明还有点未考虑 */ if(ind[v]==0){ q.push(v); res[v]=max(res[v],res[u]+1); } } } if(cnt!=n) return -1;//n个点全"输出"了才无环 return 888*n+ans; } int main(){ int x,y; while(cin>>n>>m){ for(int i=0;i<=n;i++){ g[i].clear(); ind[i]=0;res[i]=0; } while(m--){ cin>>y>>x; g[x].push_back(y); ind[y]++; } cout<<topu()<<endl; } }
12-27
334
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)