最小生成树模板

    科技2024-10-08  20

    Kruskal算法模板

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct node{ int x,y;//树一条边的起点和终点; int w;// 边权(边的价值或大小) }a[110]; int pre[110];//每个点的信息; 并查集所用; bool cmp(struct node a,struct node b) { return a.w<b.w; } int find(int root)// 查找函数(并查集) { if(root!=pre[root]) root=find(pre[root]); return pre[root]; } int main() { int n,i,m; while(scanf("%d %d",&n,&m),n) { memset(pre,0,sizeof(pre)); int sum=0,num=0; for(i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);//输入各个边的起点、终点和权值; sort(a+1,a+1+m,cmp);// 对各个边进行排序; for(i=1;i<=n;i++) pre[i]=i; for(i=1;i<=m;i++)// 从小到大开始枚举测试边;用并查集判断是否构成环; 不构成则加入; { int f1=find(a[i].x); int f2=find(a[i].y); if(f1!=f2) { pre[f1]=f2; sum+=a[i].w;//存储最小的边权和; num++; } if(num==n-1) break;// 满足树的性质; 边的条数==点的个数-1; } if(num==n-1)//判断是否存在; printf("%d\n",sum); else printf("?\n"); } return 0; }

    Prim 模板

    #include<iostream> #include<cstdio> #include<vector> #include<algorithm> #include<queue> #define ll long long using namespace std; struct node{ int to,len; node(int x,int y){to=x,len=y;} friend bool operator < (node a,node b){ return a.len>b.len; } }; int n,m; priority_queue<node>q; int ans=0; bool vis[1010]; vector<node>v[1010]; void link(int x,int y,int z){ v[x].push_back(node(y,z)); v[y].push_back(node(x,z)); } int main(){ scanf("%d%d",&n,&m); for(int i=0; i<m; i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); link(x,y,z); } vis[1]=true; for(int i=0; i<v[1].size(); i++)q.push(node(v[1][i].to,v[1][i].len)); int sum=1; while(!q.empty()){ node t=q.top(); q.pop(); if(vis[t.to])continue; sum++; ans+=t.len; vis[t.to]=true; if(sum==n)break; for(int i=0; i<v[t.to].size(); i++)if(!vis[v[t.to][i].to])q.push(node(v[t.to][i].to,v[t.to][i].len)); } if(sum==n)printf("%d\n",ans); else printf("-1\n"); return 0; }

    模板二: 模板题

    #include <iostream> #include<cstring> #include<cstdio> #include<cmath> #include<cstdlib> #define MAX 27 //图的规模 #define INF 99999999 //定义无穷大 using namespace std; int N; //节点的数目N //此外,在这里可能会有路径的数目M int map[MAX][MAX]; //邻接表 int micost[MAX]; //到上一个点的最小路径 int vis[MAX]; //记录该点有没有加入最小生成树中 void Prim() { int i,j,v,Min; int ans; //最小生成树的总权值 //1是第一个加入该最小生成树的节点 for(i=1;i<=N;i++) { micost[i]=map[1][i]; vis[i]=0; }//初始化节点 //定义每个节点的micost为1到其他点的距离 micost[1]=0; vis[1]=1; //起点的上一个节点没有节点,所以为0 //定义起点已经加入了最小生成树 ans=0; //初始化最小生成树的权值为零 //注意在循环里起点不包含进去 //为了防止错误 //因为不包含起点所以循环要从i=2开始 for(i=2;i<=N;i++) { Min=INF; for(j=2;j<=N;j++) { if(!vis[j]&&Min>micost[j]) v=j,Min=micost[j]; }//找micost最小的节点并加入最小生成树 vis[v]=1; if(Min!=INF) ans=ans+Min; for(j=2;j<=N;j++) { if(!vis[j]&&micost[j]>map[v][j]) micost[j]=map[v][j]; }//更新节点 } cout<<ans<<endl; } int main() { int i,j,num,x,y,z; char a,b; while(cin>>N,N)//输入图的节点数,路径数,(一般情况下) { for(i=1;i<=N;i++) for(j=1;j<=N;j++) { if(i==j)map[i][j]=0; else map[i][j]=INF; }//初始化邻接表 for(i=1;i<N;i++) { cin>>a>>num; for(j=1;j<=num;j++){ cin>>b>>z; x=a-64; y=b-64; map[x][y]=map[y][x]=z; } }//输入图 Prim(); } return 0; }
    Processed: 0.010, SQL: 8