• ZOJ


    题意:给出N个点,以及对应连接的费用邻接矩阵,每两个点之间连接还要额外花费 该节点的额外消费额 。问怎样连接 使得花费最小
    思路:事实上我们在建立路径的时候就把 结点额外花费的值加进去就行了

    krusal 题解:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int maxn=1e4;//点数
    const int maxm=1e6+10;//边数
    int pre[maxn];
    int cost[maxn];
    struct Edge{
        int u,v,w;
    }edge[maxm];
    int top; 
    int cnt;
    int ans;
    
    void addedge(int u,int v,int w){
        edge[top].u=u;
        edge[top].v=v;
        edge[top++].w= w + cost[u] + cost[v];
    } 
    bool cmp(Edge a,Edge b) {
        return a.w<b.w; 
    }
    int find(int x)
    {
        if(x!=pre[x]) return pre[x] = find(pre[x]);
        else return pre[x];
    }
    bool unite(int x,int y){
        int fx = find(x);
        int fy = find(y);
        if(fx!=fy) {
            pre[fx] = fy;
            cnt++;    
            return true;
        }
        else return false;
    }
    int Kruskal(int n){
        sort(edge,edge+top,cmp);//一次性把所有的边都排了 
        int u,v,w;
        for(int i=0;i<top;i++){
            u=edge[i].u;   
            v=edge[i].v;   
            w=edge[i].w; 
            if(unite(u,v)){
                ans += w;    
            }
            if(cnt==n-1) break;
        }
        if(cnt<n-1) return -1;
        return ans;
    }
    void init(int n){
        memset(edge,0,sizeof(edge));
        for(int i=0;i<=n;i++)
            pre[i] = i;
        ans = top = cnt = 0;
    } 
    int main(){
        int T;
        cin>>T;
        int n,m,w,a,b;
        while(T--){
            cin>>n;
            init(n);
            for(int i=1;i<=n;i++) cin>>cost[i];
            top=cnt=0;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    cin>>w;
                    addedge(i,j,w);
                }
            }
            cout<<Kruskal(n)<<endl;
        }
        return 0;
    }

    prim 题解:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <vector>
    #include <algorithm>
    using namespace std;
    const int maxn = 1005;
    const int maxm = 1e6+10;
    int n,m;
    int cost[maxn];
    int ans;
    typedef pair<int,int> pii;
    struct Egde{
        int u,v,w,next;
    }edge[maxm];
    struct cmp{
        bool operator () (pii a, pii b){
            return a.first > b.first;
        }
    };
    int head[maxn];
    int vis[maxn];
    int dist[maxn];
    int top;
    void init(){
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
        memset(dist,-1,sizeof(dist));
        top = 0;
        ans = 0;
    }
    void add(int u,int v,int w){
        edge[top].u = u;
        edge[top].v = v;
        edge[top].w = w+ cost[u]+cost[v];
        edge[top].next = head[u];
        head[u] = top++;
    }
    void prim(int s){
        int i;
        priority_queue<pii,vector<pii>, cmp>q;
        vis[s] = 1;
        dist[s] = 0;
        for(i = head[s];~i;i = edge[i].next){
            int v = edge[i].v;
            dist[v] = edge[i].w;
            q.push(make_pair(dist[v],v));
        }
        while(!q.empty()){
            pii t = q.top();
            q.pop();
            if(vis[t.second]) continue;
            ans += t.first;
            vis[t.second] = 1;
            
            for(i = head[t.second]; ~i;i = edge[i].next){
            int v = edge[i].v;
            if(!vis[v]&&(dist[v]>edge[i].w)||dist[v] == -1){
                dist[v] = edge[i].w;
                q.push(make_pair(dist[v],v));
                }
            }        
        }
        
    }
    int main(){
        int T;
        cin>>T;
        int n,m,w,a,b;
        while(T--){
            cin>>n;
            init();
            for(int i=1;i<=n;i++) cin>>cost[i];
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    cin>>w;
                    add(i,j,w);
                }
            }
            prim(1);
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    mass Framework event模块 v9
    关于开源的网络爬虫/网络蜘蛛larbin结构分析
    socketaddr和socketaddr_in的区别于联系
    C语言中.h和.c文件解析
    [原]变参函数原理详解
    fopen和open有什么区别?
    C语言的那些小秘密之变参函数的实现
    c语言中逗号运算符和逗号表达式
    关于REST API设计的一些小经验
    Linux信号说明列表
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11303765.html
Copyright © 2020-2023  润新知