Intelligence System
题意:一个人要传递命令给所有人,如果两人之间互达,不需任何费用,求最少费用
有向图强连通。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=0x3f3f3f3f; 4 const int maxv=50010; 5 const int maxe=100010; 6 int n,m; 7 struct Edge{ 8 int u,v,w; 9 int nex; 10 }e[maxe<<1]; 11 int head[maxv]; 12 int cnt=0; 13 void init(){ 14 memset(head,-1,sizeof(head)); 15 cnt=0; 16 } 17 void add(int u,int v,int w){ 18 e[cnt].u=u; 19 e[cnt].v=v; 20 e[cnt].w=w; 21 e[cnt].nex=head[u]; 22 head[u]=cnt++; 23 } 24 int pre[maxv],sccno[maxv],low[maxv],dfsk,scc_cnt; 25 stack<int> s; 26 void dfs(int u){ 27 s.push(u); 28 low[u]=pre[u]=++dfsk; 29 for(int i=head[u];i!=-1;i=e[i].nex){ 30 int v=e[i].v; 31 if(!pre[v]){ 32 dfs(v); 33 low[u]=min(low[u],low[v]); 34 } 35 else if(!sccno[v]) low[u]=min(low[u],pre[v]); 36 } 37 if(low[u]==pre[u]){ 38 scc_cnt++; 39 for(;;){ 40 int x=s.top(); 41 s.pop(); 42 sccno[x]=scc_cnt; 43 if(x==u) break; 44 } 45 } 46 } 47 void find_scc(int n){ 48 memset(pre,0,sizeof(pre)); 49 memset(sccno,0,sizeof(sccno)); 50 memset(low,0,sizeof(low)); 51 dfsk=scc_cnt=0; 52 for(int i=0;i<n;i++) if(!pre[i]) dfs(i); 53 } 54 int d[maxv]; 55 int main(){ 56 while(scanf("%d%d",&n,&m)!=EOF){ 57 init(); 58 int u,v,w; 59 for(int i=0;i<m;i++){ 60 scanf("%d%d%d",&u,&v,&w); 61 add(u,v,w); 62 } 63 64 find_scc(n); 65 66 for(int i=1;i<=scc_cnt;i++) d[i]=inf; 67 for(int i=0;i<n;i++){ 68 for(int j=head[i];j!=-1;j=e[j].nex){ 69 int a=sccno[e[j].u]; 70 int b=sccno[e[j].v]; 71 if(a!=b) d[b]=min(d[b],e[j].w); //不互达,费用取最小的 72 } 73 } 74 int ans=0; 75 for(int i=1;i<=scc_cnt;i++) 76 if(d[i]!=inf) ans+=d[i]; 77 printf("%d ",ans); 78 } 79 }