強連通分量1.5HDU 3072 Intelligence System
阿新 • • 發佈:2018-12-18
給定一張圖,問0點到達其餘點的最小代價
#include<cstdio> #include<cstring> #include<vector> #include<algorithm> #include<stack> using namespace std; const int maxn=50000+10; int n,m; vector<int> G[maxn],cost[maxn]; stack<int> S; int dfs_clock, scc_cnt; int pre[maxn],low[maxn],sccno[maxn]; int val[maxn];//val[i]=x表第i個分量的入邊中代價最小為x void dfs(int u) { pre[u]=low[u]=++dfs_clock; S.push(u); for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(!pre[v]) { dfs(v); low[u]=min(low[u],low[v]); } else if(!sccno[v]) low[u]=min(low[u],pre[v]); } if(low[u]==pre[u]) { scc_cnt++; while(true) { int x=S.top(); S.pop(); sccno[x]=scc_cnt; if(x==u) break; } } } void find_scc(int n) { dfs_clock=scc_cnt=0; memset(pre,0,sizeof(pre)); memset(sccno,0,sizeof(sccno)); for(int i=0;i<n;i++) if(!pre[i]) dfs(i); } int main() { while(scanf("%d%d",&n,&m)==2) { for(int i=0;i<n;i++) G[i].clear(),cost[i].clear(); while(m--) { int u,v,w; scanf("%d%d%d",&u,&v,&w); G[u].push_back(v); cost[u].push_back(w); } find_scc(n); for(int i=1;i<=scc_cnt;i++) val[i]=1e6; for(int u=0;u<n;u++) for(int i=0;i<G[u].size();i++) { int v=G[u][i];//u點與之相鄰的點; int x=sccno[u], y=sccno[v];//若兩點不屬於同一聯通分量 if(x!=y) val[y]=min(val[y],cost[u][i]);//入度最小的值; }//除0點以外的縮點入度都>=1,找到各個縮點入度的最小值,加起來即可; int ans=0; for(int i=1;i<=scc_cnt;i++)if(i!=sccno[0]) ans+= val[i];//加上所有縮點的入度最小值; printf("%d\n",ans); } return 0; }