「Luogu P2002」消息扩散 发表于 2018-08-11 | 字数统计: 359 | 阅读时长 ≈ 2 给出一个有向图,消息沿着边扩散,求最少需要在几个点发消息才能使整个图所有点都得到消息。 代码1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495#include<bits/stdc++.h>using namespace std;typedef int ll;struct edge{ ll to,prev;};edge ed[500001],scc[500001];ll test,tot,num,top,cnt,nc,ec,ans;ll last[500001],sccLast[500001],dfn[500001],low[500001],ins[500001],belong[500001];ll from[500001],to[500001],size[500001],in[500001];stack<ll>st;inline void addEdge(ll from,ll to){ ed[++tot].to=to; ed[tot].prev=last[from]; last[from]=tot;}inline void addSCC(ll from,ll to){ scc[++tot].to=to; scc[tot].prev=sccLast[from]; sccLast[from]=tot;}inline void tarjan(ll node){ dfn[node]=low[node]=++num; st.push(node),ins[node]=1; ll flag=0,to; for(register int i=last[node];i;i=ed[i].prev) { to=ed[i].to; if(!dfn[to]) { tarjan(to); low[node]=min(low[node],low[to]); } else { if(ins[to]) { low[node]=min(low[node],dfn[to]); } } } if(dfn[node]==low[node]) { cnt++; ll nd; do { nd=st.top(),st.pop(); ins[nd]=0; belong[nd]=cnt; size[cnt]++; } while(node!=nd); }}inline void mergePoint(){ tot=0; for(register int i=0;i<ec;i++) { if(belong[from[i]]!=belong[to[i]]) { addSCC(belong[from[i]],belong[to[i]]); in[belong[to[i]]]++; } }}int main(){ cin>>nc>>ec; for(register int i=0;i<ec;i++) { cin>>from[i]>>to[i]; addEdge(from[i],to[i]); } for(register int i=1;i<=nc;i++) { if(!dfn[i]) { tarjan(i); } } mergePoint(); for(register int i=1;i<=cnt;i++) { if(!in[i]) { ans++; } } cout<<ans<<endl;} 本文作者: Karry5307 本文链接: http://karry5307.github.io/2018/08/11/「Luogu-P2002」消息扩散/ 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!