#include #define Nmax 200005 #define INF 0x3f3f3f3f using namespace std; vector > G[Nmax]; vector Gt[Nmax],SCC[Nmax],SCCT[Nmax],order; bitsetused,inQ; stack S; queue Q; int N,M,scc[Nmax],nrc,bune[Nmax],ciclu[Nmax],OUT[Nmax]; int DP[Nmax]; int Size[Nmax],NRQ[Nmax]; void Read() { scanf("%d%d",&N,&M); int a,b,c; for(int i = 1; i <= M; ++i) { scanf("%d%d%d",&a,&b,&c); G[a].push_back({c,b}); Gt[b].push_back(a); } order.resize(N); for(int i = 1; i <= N; ++i) order[i-1] = i; random_shuffle(order.begin(),order.end()); for(int i = 1; i <= N; ++i) if(G[i].size()) random_shuffle(G[i].begin(),G[i].end()); } void DFS(int k){ used[k] = 1; for(auto it : G[k]) if(!used[it.second]) DFS(it.second); S.push(k); } void DFST(int k){ used[k] = 1; scc[k] = nrc; /// k apartine componentei tare conexe cu nr curent nrc Size[nrc]++; for(auto it : Gt[k]) if(!used[it]) DFST(it); } void Kosaraju() { int k; for(int i = 1; i <= N; ++i) if(!used[i]) DFS(i); used = 0; while(!S.empty()) { k = S.top(); S.pop(); if(used[k] == 1) continue; ++nrc; DFST(k); } } int Bellman_Ford(int k) { int tip = scc[k]; DP[k] = 0; Q.push(k); inQ[k] = 1; NRQ[k]++; while(!Q.empty()) { k = Q.front(); Q.pop(); inQ[k] = false; for(auto it : G[k]) if(scc[it.second] == tip && DP[it.second] > DP[k] + it.first) { DP[it.second] = DP[k] + it.first; if(inQ[it.second] == true) continue; Q.push(it.second); inQ[it.second] = true; NRQ[it.second] ++; if(NRQ[it.second] > min(Size[tip],200)) { while(!Q.empty()) Q.pop(); return 1; } } } return 0; } void Get_Negative() { memset(DP,INF,sizeof(DP)); used = 0; int flag; for(int xx = 0; xx < N; ++xx){ int i = xx + 1;///order[xx]; if(!used[scc[i]]){ used[scc[i]] = 1; flag = Bellman_Ford(i); if(flag == 1) ciclu[scc[i]] = 1; } } } void Build_Graph() { int a,b; for(int i = 1; i <= N; ++i) for(auto it : G[i]) { a = i; b = it.second; if(scc[a] == scc[b]) ///|| pusa[{scc[a],scc[b]}] == 1) continue; ///pusa[{scc[a],scc[b]}] = 1; ++OUT[scc[a]]; SCC[scc[a]].push_back(scc[b]); SCCT[scc[b]].push_back(scc[a]); } } void Desfrunzire() { for(int i = 1; i <= nrc; ++i) if(SCC[i].size() == 0 && ciclu[i] == 0) Q.push(i); int k = 0; while(!Q.empty()) { k = Q.front(); bune[k] = 1; Q.pop(); for(auto it : SCCT[k]) { OUT[it]--; if(OUT[it] == 0 && ciclu[it] == 0) Q.push(it); } } int cnt = 0; for(int i = 1; i <= N; ++i) if(bune[scc[i]] == 0) ++cnt; printf("%d\n",cnt); } int main() { ///freopen("ciclu.in","r",stdin); ///freopen("ciclu.out","w",stdout); Read(); Kosaraju(); Get_Negative(); Build_Graph(); Desfrunzire(); return 0; }