资讯详情

每日总结(2022/2/16)

1.上午(2h)

或者看最小生成树的视频和博客

从下午到晚上(6)h)

1.刷出三道题。

2.模板题有两种方法

题目描述

例如,给出一个无向图,找出最小生成树。如果图不连接,则输出orz

输入格式

第一行包含两个整数N,MN,M,表示图共有NN个结点和MM条无向边。

接下来MM每行包含三个整数X_i,Y_i,Z_iXi,Yi,Zi,这意味着有一个长度Z_iZi无向边连接点X_i,Y_iXi,Yi。

输出格式

如果图片连接,则输出一个整数表示生成树的最小长度之和。如果图片不连接,则输出orz

输入输出样例

复制

4 5 1 2 2 1 3 2 1 4 3 2 3 4 3 4 3

复制

7

说明/提示

数据规模:

对于20\ %的数据,N\le 5N≤5,M\le 20M≤20。

对于40\@%的数据,N\le 50N≤50,M\le 2500M≤2500。

对于70\p%的数据,N\le 500N≤500,M\le 10^4M≤104。

对于100\0%的数据:1\le N\le 50001≤N≤5000,1\le M\le 2\times 10^51≤M≤2×105,1\le Z_i \le 10^41≤Zi≤104。

样例解释:

因此,最小生成树的总边权是2 2 3=72 2 3=7。

方法一:Prim

#include<bits/stdc  .h> using namespace std; #define inf 123456789 #define maxn 5005 #define maxm 200005 int head[maxn],dis[maxn],cnt,tot,n,m,now=1,ans=0; bool vis[maxn]; struct node{  int s;  int e;  int next; }e[maxm]; void add(int a,int b,int c)//前向星  {  cnt  ;  e[cnt].s=b;  e[cnt].e=c;  e[cnt].next=head[a];  head[a]=cnt; } int prim() {  for(int i=2;i<=n;i  )//初始化为最大   {   dis[i]=inf;  }  for(int i=head[1];i;i=e[i].next)//更新   {   dis[e[i].s]=min(dis[e[i].s],e[i].e);  }  while(  tot<n)  {   int minn=inf;   vis[now]=1;   for(int i=1;i<=n;i  )   {    if(!vis[i]&&minn>dis[i])////此时更改点连接找到最小点     {     minn=dis[i];     now=i;     }    }   ans =minn;   for(int i=head[now];i;i=e[i].next)   {    int k=e[i].s;    if(dis[k]>e[i].e&&!vis[k])    {     dis[k]=e[i].e;    }   }  }  return ans; } int main() {  cin>>n>>m;  for(int i=1;i<=m;i  )  {   int a,b,c;   cin>>a>>b>>c;   add(a,b,c);//双向    add(b,a,c);  }  printf("%d",prim()); } 

方法二:并收集,kruskal

#include<iostream> #include<algorithm> using namespace std;  int p[5005] struct node {     int a,b,v; }mp[500000]; bool cmp(node a,node b)//排序 {     return a.v<b.v; } int find(int x)//找祖宗 {     int r=x;     while(p[r]!=r&&p[r]!=0)         r=p[r];     return p[x]=r; } int kruskal(int n,int m)//类似于贪婪 {     int ans=0,cnt=0;     sort(mp 1,mp 1 m,cmp);     for(int i=1;i<=m;i  )     {         int x=find(mp[i].a);         int y=find(mp[i].b);         if(x==y)//判断是否成环         continue;         ans =mp[i].v;         p[x]=y;         if(  cnt==n-1)            break;     }     for(int i=1;i<n;i  )         if(find(i)!=find(i 1))ans=0;     return ans; } int main() {     int n,m,a,b,v;     cin>>n>>m;     for(int i=1;i<=m;i  )     {         cin>>a>>b>>v;         mp[i].a=a;         mp[i].b=b;         mp[i].v=v;     }     int ans=kruskal(n,m);     if(ans)         cout<<ans;     else cout<<"orz";     return 0; }

标签: 500n扭距传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台