最小生成树 prime + 队列优化
最小生成树prime+队列优化
优化后时间复杂度是O(m*lgm) m为边数
优化后简直神速,应该说对于绝大多数的题目来说都够用了
具体有多快呢 请参照这篇博客:堆排序 Heapsort
///prime队列优化 #include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #define ll long long #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define mem(a) memset(a,0,sizeof(a)) using namespace std; const int N=50000; struct Edge{ int to; int w; friend bool operator< (Edge a,Edge b){ return a.w>b.w; } }; vector<Edge>Map[N]; ///vector[i][j]存图表示从第i个节点出发的第j条边的情况 void Add_Edge(int u,int v,int w){ Edge e; e.to=v,e.w=w; Map[u].push_back(e); } void prime(int n){ int ans=0; Edge now; int vis[N]; mem(vis); priority_queue<Edge>Q; while(!Q.empty()) Q.pop(); for(int i=0; i<Map[1].size(); i++) Q.push(Map[1][i]); vis[1]=1; n--; while(n--){ now=Q.top(); Q.pop(); if(vis[now.to]) while(vis[now.to]){ now=Q.top(); Q.pop(); } ans+=now.w; vis[now.to]=1; for(int i=0; i<Map[now.to].size(); i++) if(!vis[Map[now.to][i].to]) Q.push(Map[now.to][i]); } printf("%d\n",ans); } int main(){ int n,m,u,v,w; while(scanf("%d%d",&n,&m)!=EOF){ for(int i=0; i<m; i++){ scanf("%d%d%d",&u,&v,&w); Add_Edge(u,v,w); Add_Edge(v,u,w); } prime(n); } return 0; }