aaa

//prim 未优化
scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z);//加边 edge[x][y]=edge[y][x]=z; } memset(dis,127/3,sizeof(dis)); dis[1]=0;boo[1]=1;//由结点1开始生成最小生成树,boo[1]=1,表示结点1已经加入最小生成树 for(int i=2;i<=n;i++){ if(edge[1][i]) dis[i]=min(dis[i],edge[1][i]);//更新和结点1相连的点的值 } for(int i=1;i<=n-1;i++){//生成n-1条边 maxx=0; for(int j=1;j<=n;j++){ if(!boo[j])//找一个点没加入最小生成树并且距离已经生成的树的距离最小的 if(!maxx||dis[maxx]>dis[j]) maxx=j; } boo[maxx]=1;//将它加入最小生成树 ans+=dis[maxx];//加入答案 for(int j=1;j<=n;j++){//将它更新其他点到最小生成树的距离; if(!boo[j]) if(edge[maxx][j]) dis[j]=min(dis[j],edge[maxx][j]); } } printf("%d",ans); return 0; } prim算法的优化 //prim的队列优化 #include <bits/stdc++.h> using namespace std; const int maxn=100000+15; const int maxm=100000+15; struct Edge { int x,y,z,next; Edge(int x=0,int y=0,int z=0,int next=0):x(x),y(y),z(z),next(next) {} }edge[maxm*2]; const bool operator < (const Edge &a,const Edge &b) //为了优先队列取边时,将权值最小的边先取出 { return a.z>b.z; } int n,m; int sumedge,head[maxn]; int ins(int x,int y,int z) { edge[++sumedge]=Edge(x,y,z,head[x]); return head[x]=sumedge; } priority_queue <Edge> que;//优先队列 里面的内容是一个结构体 是没条边的x,y,z,next; int ans; bool boo[maxn];//标记有没有加入最小生成树 int main() { scanf("%d%d",&n,&m);//输入n个点m条边 for (int i=1;i<=m;i++) { int x,y,z;//输入起点,终点,权值 scanf("%d%d%d",&x,&y,&z); ins(x,y,z);//链表建边 ins(y,x,z); } memset(boo,false,sizeof(boo));//没有加入最小生成树 boo[1]=true;//结点1加入最小生成树;从结点1开始生成最小生成树; for (int u=head[1];u;u=edge[u].next) que.push(edge[u]);//将和1相连的边入队 for (int i=1;i<n;i++) //总共有n-1条边 { Edge temp; temp=que.top();//取出距离1结点长度最小的边 for (;boo[temp.y];que.pop(),temp=que.top());//当这个边的终点已经加入最小生成树,就删除这条边,取次小的边 que.pop();//删除这条边 已经加入最小生成树 留着也没用 ans+=temp.z;//加上这条边的权值 boo[temp.y]=true;//这条边的终点加入最小生成树 temp是一个结构体 for (int u=head[temp.y];u;u=edge[u].next)//扫一遍和现在的点相连的边 if (!boo[edge[u].y]) que.push(edge[u]);//将没有在最小生成树中的边入队; } printf("%d ",ans); return 0; } (2)kruskal 并查集 贪心 每次加入长度最小边 前提是边的起点和终点不在一个并查集里 否则会形成环 #include<bits/stdc++.h> using namespace std; const int maxn=100000; int n,m,x,y,z,far[maxn],ans; const int oo=1234567 struct Edge { int x,y,z; Edge(int x=0,int y=0,int z=oo): x(x),y(y),z(z) {} }edge[maxn]; bool cmp(Edge a,Edge b) { return a.z<b.z; } int f(int x) { return far[x]==x?x:far[x]=f(far[x]); } void unionn(int x,int y) { far[f(x)]=f(y); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); edge[i]=Edge(x,y,z);//这样对结构体赋值要在结构体里写个Edge(int ------) } sort(edge+1,edge+m+1,cmp); for(int i=1;i<=n;i++) { far[i]=i; } for(int i=1;i<=m;i++) { int p=edge[i].x,q=edge[i].y; if(f(p)!=f(q)){ unionn(p,q); ans+=edge[i].z; } } printf("%d",ans); return 0; } 3、最小瓶颈生成树 最小瓶颈生成树为使所有的生成树中最大权值最小 最小生成树一定是最小瓶颈生成树 最小瓶颈生成树不一定是最小生成树 4、最优比率生成树 二分思想 改日再添 5、最短路径 (1)dijkstra 求单源最短路

 1、大根堆优先队列维护

#include<bits/stdc++.h>
using namespace std;
priority_queue<int>heap;
int m,x,od;
int main()
{
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d",&od);
        if(od==1)
        printf("%d",heap.top());
        if(od==2)
        {
            scanf("%d",&x);
            heap.push(x);
        }
        if(od==3)
        {
            heap.pop();
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zzyh/p/6786331.html