复制代码

最小生成树

算法一:prime

特别好用的 O(n^2)和dij 差了两行

 

#include<bits/stdc++.h>
using namespace std;
#define LOACL  freopen("in","r",stdin);\
            freopen("out","w",stdout); 

#define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) 
#define f(i,l,r) for(int i=l;i<=r;++i)
#define g(i,l,r) for(int i=l;i>=r;--i)
#define CLR(arr,val) memset(arr,val,sizeof(arr))

typedef long long ll;
const int sz = (int)1e4+6; 
const int inf =0x3f3f3f;


int n,sum;
int g[sz][sz],dis[sz],vis[sz];
void prim()
{
    f(i,1,n)dis[i]=g[1][i];
    vis[1]=1;
//    int ans= 0;
    f(i,1,n-1)
    {
        int mm = inf ,pos;
        f(j,1,n)
        {
            if(!vis[j]&& dis[j]< mm)
            {
                mm =dis[j];
                pos =j;
            }  
        }
        if(mm==inf)break;
        vis[pos]=1;
        f(j,1,n)
        {
            if(!vis[j] && dis[j]>g[pos][j])
            {
                dis[j]=g[pos][j];
            }
        }
    }
}
int main()
{
    LOACL
    
    CLR(dis,inf);
    CLR(vis,0);
    cin>>n;
    f(i,1,n)f(j,1,n)cin>>g[i][j];
    prim();
    f(i,1,n)sum+=dis[i];

    cout<<sum<<endl; 


    return 0;
}
View Code

算法二:krsucal

适用范围: 稀疏图

原理:查并集+贪心 巨简单好写

#include<bits/stdc++.h>
using namespace std;
#define LOACL  freopen("in","r",stdin);\
            freopen("out","w",stdout); 

#define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) 
#define f(i,l,r) for(int i=l;i<=r;++i)
#define g(i,l,r) for(int i=l;i>=r;--i)
#define CLR(arr,val) memset(arr,val,sizeof(arr))

typedef long long ll; 
const int sz =1e6+5;
int n,m ;
 
struct node
{
    int u,v,w;
}no[sz];
bool cmp(node l,node r)
{
    return l.w<r.w;
}
int fa[sz];
 
int getf(int x)
{
    if(x!=fa[x]) fa[x] =getf(fa[x]);
    return fa[x];
}
void uni(int x,int y)
{
    int fx = getf(x);
    int fy = getf(y);
    if(fx!=fy)fa[fx]=fy;
}
int krusal()
{
    int ans=0;
     
    f(t,1,m)
    if(getf(no[t].u) != getf ( no[t].v))
    { 
        uni(no[t].u,no[t].v);
        ans+=no[t].w ;
    }
    return ans; 
}
int main()
{
    LOACL
    cin>>n>>m;
    f(i,1,m) cin>>no[i].u>>no[i].v>>no[i].w;
    sort(no+1,no+m+1,cmp);
    f(i,1,n)fa[i]=i;
    printf("%d",krusal());
    return 0;
}
View Code

算法三: 堆优化prime

适用范围:稀疏图

顺便写一下stl堆操作

参考大佬链接

#include<bits/stdc++.h>
using namespace std;
#define LOACL  freopen("in","r",stdin);\
            freopen("out","w",stdout); 

const int  inf = 987654321;
const int sz = 1e6 + 5;
const int mod = 1e9 + 7;
const int sqrtn = 300; 

#define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) 
#define f(i,l,r) for(int i=l;i<=r;++i)
#define g(i,l,r) for(int i=l;i>=r;--i)
#define CLR(arr,val) memset(arr,val,sizeof(arr)) 
typedef long long ll; 

int main()
{
    LOACL
    int arr[]={123,45,15,151,351,23145,343,} ;
    vector<int> v;
    f(i,0,sizeof(arr)/sizeof(arr[0])-1)
        v.push_back(arr[i]);
    make_heap(v.begin(),v.end());
    
    cout<<v.front()<<endl;

    pop_heap(v.begin(),v.end()); v.pop_back();

    v.push_back(4444444);
    push_heap(v.begin(),v.end());
    cout<<v.front()<<endl;

    sort_heap (v.begin(),v.end());
    cout<<v.front()<<endl;
    sort_heap (v.begin(),v.end());
    cout<<v.front()<<endl;
 


    return 0;
}
View Code

 

 

 

#include<bits/stdc++.h>
using namespace std;
#define LOACL  freopen("in","r",stdin);\
            freopen("out","w",stdout); 

const int  inf = 987654321;
const int sz = 1e6 + 5;
const int mod = 1e9 + 7;
const int sqrtn = 300; 

#define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) 
#define f(i,l,r) for(int i=l;i<=r;++i)
#define g(i,l,r) for(int i=l;i>=r;--i)
#define CLR(arr,val) memset(arr,val,sizeof(arr)) 
typedef long long ll; 
struct node 
{
    int u,v,w;
    bool operator < (const struct node & n)const
    {
        return w > n.w; 
    }
};
vector<node> heap;
vector<node>g[sz];
bool vis[sz];
int n,m,u,v,w;
void push(node & n)
{
    heap.push_back(n);
    push_heap(heap.begin(),heap.end());
}
void pop()
{
    pop_heap(heap.begin(),heap.end());
    heap.pop_back();
}
int main()
{
    LOACL
    cin>>n>>m;
    f(i,1,m)
    {
        cin>>u>>v>>w;
        g[u].push_back((node){u,v,w});
        g[v].push_back((node){v,u,w});        
    } 
    vis[1]=1;
    f(i,0,g[1].size()-1)
    {
        push(g[1][i]);
    }
    int all=0;
    int cnt= 0;
    while(cnt<n-1)
    {
        int w= heap[0].w;
        int v = heap[0].v;
        pop();
        if(vis[v])continue;
        vis[v]=true;
        all+=w;
        cnt++;
        f(i,0,g[v].size()-1)
        {
            if(!vis[g[v][i].v])
                push(g[v][i]);
        }

    }
    cout<<all<<endl;
    return 0;
}
View Code

 

posted @ 2018-03-13 20:37  pg633  阅读(179)  评论(0)    收藏  举报