最小生成树: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进行映射

经典题目字符串哈希