hdu 3072

xiaoxiao2021-02-28  82

学习了最小树形图 题解:http://www.cnblogs.com/wust-ouyangli/p/5722496.html


努力理解了最小树形图的原理 对于这道题 我个人感觉是类似于dijkstra 因为首先这个是一定能找到通路的,既然这样就不断更新(不管从哪里)到这个点的最小花费


#include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <stack> #include <queue> using namespace std; const int maxn=50010; const int vm=100010; const int INF=0x3f3f3f3f; struct points { int v,c; }; vector<int> G[vm]; int n; int dis[maxn],vis[maxn],inq[maxn]; int uu[vm],vv[vm],ww[vm]; int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt; stack<int> S; void dfs(int u) { pre[u]=lowlink[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); lowlink[u]=min(lowlink[u],lowlink[v]); } else if (!sccno[v]) lowlink[u]=min(lowlink[u],pre[v]); } if (lowlink[u]==pre[u]) { scc_cnt++; for (;;) { 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(sccno,0,sizeof(sccno)); memset(pre,0,sizeof(pre)); for (int i=0;i<n;i++) if (!pre[i]) dfs(i); } int main() { int m,ans; while (~scanf("%d%d",&n,&m)) { for (int i=0;i<=n;i++) G[i].clear(); for (int i=1;i<=m;i++) { scanf("%d%d%d",&uu[i],&vv[i],&ww[i]); G[uu[i]].push_back(vv[i]); } find_scc(n); for (int i=1;i<=scc_cnt;i++) dis[i]=INF; for (int i=1;i<=m;i++) { int u=sccno[uu[i]],v=sccno[vv[i]]; // printf("u=%d v=%d w=%d\n",u,v,ww[i]); if (v!=u) dis[v]=min(dis[v],ww[i]); } n=scc_cnt; ans=0; for (int i=1;i<=scc_cnt;i++) { if (i!=sccno[0]) ans+=dis[i]; } printf("%d\n",ans); } return 0; }
转载请注明原文地址: https://www.6miu.com/read-70695.html

最新回复(0)