最小生成树:prim
与dijkstar相似,也可用堆优化
1 struct Edge{ 2 int to; 3 int next; 4 int w; 5 }edge[N*3]; 6 int first[N*3]; 7 int cnt=0; 8 void add(int u,int v,int w){ 9 edge[++cnt].to=v; 10 edge[cnt].w=w; 11 edge[cnt].next=first[u]; 12 first[u]=cnt; 13 } 14 int dis[N]; 15 bool vis[N]; 16 struct node{ 17 int dex; 18 int d; 19 node(){ 20 21 } 22 node(int x,int y){ 23 dex=x; 24 d=y; 25 } 26 bool operator< (const node&a) const{ 27 return this->d>a.d;//小根堆为大于 28 } 29 }; 30 int n,m; 31 priority_queue<node>q; 32 int prim(){ 33 memset(vis,0,sizeof(vis)); 34 memset(dis,127,sizeof(dis)); 35 dis[1]=0; 36 node tmp(1,0); 37 q.push(tmp); 38 int ans=0; 39 int num=0; 40 while(!q.empty()){ 41 num++; 42 tmp=q.top(); 43 q.pop(); 44 int x=tmp.dex; 45 if(vis[x]) 46 continue; 47 vis[x]=1; 48 ans+=dis[x]; 49 for(int i=first[x];i;i=edge[i].next){ 50 int v=edge[i].to; 51 if(!vis[v]&&dis[v]>edge[i].w){ 52 dis[v]=edge[i].w; 53 q.push(node(v,dis[v])); 54 } 55 } 56 } 57 if(num<n){ 58 ans=-1; 59 } 60 return ans; 61 }//prim生成最短路
Kruskal求最小生成树,贪心加并查集,将边从小到大进行排序,依次添加
1 struct edge{ 2 int from; 3 int to; 4 int w; 5 }e[N]; 6 bool cmp(edge a,edge b){ 7 return a.w<b.w; 8 } 9 int n,m; 10 int fa[N]; 11 int f(int x){ 12 if(fa[x]==x) 13 return x; 14 return fa[x]=f(fa[x]); 15 } 16 void merge(int x,int y){ 17 fa[f(x)]=f(y); 18 } 19 int ans=0; 20 int main(){ 21 cin>>n>>m; 22 for(int i=1;i<=n;++i){ 23 fa[i]=i; 24 } 25 for(int i=0;i<m;++i){ 26 int a,b,c; 27 cin>>a>>b>>c; 28 e[i].from=a; 29 e[i].to=b; 30 e[i].w=c; 31 } 32 sort(e,e+m,cmp); 33 for(int i=0;i<m;++i){ 34 int u=e[i].from; 35 int v=e[i].to; 36 if(f(u)!=f(v)){ 37 merge(u,v); 38 ans+=e[i].w; 39 } 40 } 41 int dex=f(1); 42 for(int i=2;i<=n;++i){ 43 if(f(i)!=dex){ 44 ans=-1; 45 break; 46 } 47 } 48 if(ans==-1){ 49 cout<<"orz"<<endl; 50 }else{ 51 cout<<ans<<endl; 52 } 53 return 0; 54 }//Kruskal求最小生成树
二叉树多是递归,注意先序中序后序的性质
以及递归停止条件
哈希表示一一对应关系,用法是将不好表示的东西映射成较小的数字,比如输入数字过大,可以用string映射int;还可以用来判断两个字符串是否相等,一般我们直接用map进行映射
经典题目字符串哈希
浙公网安备 33010602011771号