51nod 1443 路径和树(单元最短路径)
Posted 7391_KID
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1443 路径和树(单元最短路径)相关的知识,希望对你有一定的参考价值。
分析:很容易想到先搞一遍单源最短路径,然后只保留最短路径上的边,接下来容易想到最小生成树,但是因为有的边只删了一个方向,所以变成了有向图了,要求的就是最小树形图,比较麻烦而且容易T。。。
实际上,考虑在连好的图里加一个点,肯定是加连向它的最短边,类似贪心的思路,所以结果就是删完后的图中,每个点的最小前驱边权的和。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<vector> 6 #include<algorithm> 7 using namespace std; 8 typedef long long ll; 9 const int maxn=3e5+5; 10 const ll inf=1e18; 11 struct Edge{ 12 int u,v; 13 ll w; 14 Edge(int _u,int _v,ll _w):u(_u),v(_v),w(_w){} 15 }; 16 bool Cmp(Edge a,Edge b){ 17 return a.w<b.w; 18 } 19 vector<Edge> edges; 20 vector<int>G[maxn]; 21 void AddEdge(int u,int v,ll w){ 22 edges.push_back(Edge(u,v,w)); 23 edges.push_back(Edge(v,u,w)); 24 G[u].push_back(edges.size()-2); 25 G[v].push_back(edges.size()-1); 26 } 27 28 int u,n,m; 29 ll dis[maxn]; 30 ll pre[maxn]; 31 bool inq[maxn]; 32 void spfa(){ 33 memset(inq,0,sizeof(inq)); 34 memset(pre,0,sizeof(pre)); 35 for(int i=1;i<=n;i++)dis[i]=inf; 36 queue<int> Q; 37 Q.push(u); 38 inq[u]=true; 39 dis[u]=0; 40 while(!Q.empty()){ 41 int x=Q.front();Q.pop(); 42 inq[x]=false; 43 for(int i=0;i<G[x].size();i++){ 44 Edge &e=edges[G[x][i]]; 45 if(dis[e.v]>dis[e.u]+e.w){ 46 dis[e.v]=dis[e.u]+e.w; 47 pre[e.v]=e.w; 48 if(!inq[e.v]){inq[e.v]=true;Q.push(e.v);} 49 } 50 else if(dis[e.v]==dis[e.u]+e.w)pre[e.v]=min(pre[e.v],e.w); 51 } 52 } 53 } 54 int main(){ 55 // freopen("e:\\\\in.txt","r",stdin); 56 int from,to; 57 ll weight; 58 scanf("%d%d",&n,&m); 59 for(int i=0;i<m;i++){ 60 scanf("%d%d%lld",&from,&to,&weight); 61 AddEdge(from,to,weight); 62 } 63 scanf("%d",&u); 64 spfa(); 65 ll ans=0; 66 for(int i=1;i<=n;i++){ 67 ans+=pre[i]; 68 } 69 printf("%lld\\n",ans); 70 return 0; 71 }
以上是关于51nod 1443 路径和树(单元最短路径)的主要内容,如果未能解决你的问题,请参考以下文章