Cod sursa(job #1365150)

Utilizator PTAdrian64Pop-Tifrea Adrian PTAdrian64 Data 28 februarie 2015 09:12:04
Problema Arbore partial de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.62 kb
#include <cstdio>
#include <vector>
#define nmaxv 200010
#define inf 0x3f3f3f3f
#include <algorithm>
#include <vector>

using namespace std;

int n,lh;
int cost[nmaxv],cap[nmaxv],poz[nmaxv];
int heap[nmaxv];
vector <pair<int,int> > graph[nmaxv];
vector <pair<int,int> > apcm;
int ans;

inline int father(int k){
    return k>>1;
}

inline int left_son(int k){
    return k<<1;
}

inline int right_son(int k){
    return (k<<1)|1;
}

void sift(int k){
    int son;
    do{
        son = 0;
        if(left_son(k) <= lh){
            son = left_son(k);
            if(right_son(k) <= lh && cost[heap[right_son(k)]] < cost[heap[son]])son = right_son(k);
            if(cost[heap[k]] <= cost[heap[son]])son = 0;
        }
        if(son){
            swap(heap[son],heap[k]);
            swap(poz[heap[son]],poz[heap[k]]);
            k = son;
        }
    }while(son);
}

void percolate(int k){
    while(k > 1 && cost[heap[k]] < cost[heap[father(k)]]){
        swap(heap[k],heap[father(k)]);
        swap(poz[heap[k]],poz[heap[father(k)]]);
        k = father(k);
    }
}

void add_heap(int k){
    heap[++lh] = k;
    poz[k] = lh;
    percolate(lh);
}

int heap_top(){
    int x = heap[1];
    swap(heap[1],heap[lh]);
    swap(poz[heap[1]],poz[heap[lh]]);
    lh--;
    sift(1);
       poz[x] = 0;
    return x;
}

void read(){
    scanf("%d ",&n);
    int x,y,z;
    while(scanf("%d %d %d ",&x,&y,&z) != EOF){
        graph[x].push_back(make_pair(z,y));
        graph[y].push_back(make_pair(z,x));
    }
}

void atasaza_la_arbore(int x){
    for(int i = 0;i < graph[x].size();++i){
        int node = graph[x][i].second;
        int pret = graph[x][i].first;
        cost[node] = min(cost[node],pret);
        if(cost[node] == pret)
            cap[node] = x;
    }
}

void prim(){
   for(int i = 1;i <= n;i++)cost[i] = inf;
    cost[1] = 0;
    atasaza_la_arbore(1);
    for(int i = 2;i <= n;i++)add_heap(i);
    int x;
    for(int i = 1;i < n;i++){
        x = heap_top();
        atasaza_la_arbore(x);
        ans += cost[x];
        apcm.push_back(make_pair(x,cap[x]));
        for(int j = 0;j <graph[x].size();++j){
            int node = graph[x][j].second;
            if(poz[node])
                percolate(poz[node]);
        }
    }
}

void print(){
    printf("%d\n",ans);
    printf("%d\n",n-1);
    for(vector <pair<int,int> > :: iterator it = apcm.begin();it != apcm.end();++it)printf("%d %d\n",it->first,it->second);
}

int main(void){
    freopen("apm.in","r",stdin);
    freopen("apm.out","w",stdout);
    read();
    prim();
    print();
}