Cod sursa(job #1192327)

Utilizator hellol30FMI Macovei Daniel hellol30 Data 28 mai 2014 21:22:04
Problema Arbore partial de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.95 kb
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define DIM 10000
char buff[DIM];
int pozbuff=0;

void scan(int &numar){
	numar = 0;    
	while (buff[pozbuff] < '0' || buff[pozbuff] > '9')     
		if (++pozbuff == DIM) fread(buff,1,DIM,stdin),pozbuff=0;          
	while ('0'<=buff[pozbuff] && buff[pozbuff]<='9'){
		numar = numar*10 + buff[pozbuff] - '0';
		if (++pozbuff == DIM) fread(buff,1,DIM,stdin),pozbuff=0;               
	}     
}
class Arbore{
	vector<int> t, vec, heap, poz;
	vector< vector<pair<int,int> > > vecini[2];
	vector<pair<int,int> >  d;
	int n,m,indice,x,y,z, cost;
public:
	Arbore(){
		indice=0;
		citire();
	}
	void insertAPM(int x){
		for(unsigned int i = 0;i < vecini[0][x].size(); ++i) {
			int nod = vecini[0][x][i].first;
			int cost = vecini[0][x][i].second;
			t[nod] = min(t[nod],cost);
			if( t[ nod ] == cost) vec[ nod ] = x;
		}
	}
	void push(int nod){
		while((nod * 2 <= indice && t[ heap[nod] ] > t[ heap[nod * 2] ]) 
				|| (nod * 2 + 1 <= indice && t[heap[indice]] > t[heap[nod * 2 + 1]])){
			if (t[heap[nod * 2]] < t[heap[nod * 2 + 1]] || nod * 2 + 1 > indice){
				swap(heap[nod],heap[nod * 2]);
				swap(poz[heap[nod]],poz[heap[nod * 2]]);
				nod *= 2;
			}
			else {
				swap(heap[nod],heap[nod * 2 + 1]);
				swap(poz[heap[nod]],poz[heap[nod * 2 + 1]]);
				nod = nod * 2 + 1;
			}
		}
	}
	void pop(int nod){
		while(nod > 1 && t[ heap[nod] ] < t[ heap[nod / 2]] ) {
			swap(heap[nod],heap[nod / 2]);
			swap(poz[heap[nod]],poz[heap[nod / 2]]);
			nod = nod / 2;
		}
	}
	void insertHEAP(int nod){
		heap[++indice] = nod;
		poz[nod] = indice;
		pop(indice);
	}
	int peekHEAP() {
		int x = heap[1];
		swap(heap[1],heap[indice]);
		swap(poz[heap[1]],poz[heap[indice]]);
		indice--;
		push(1);
		poz[x] = 0;
		return x;
	}
	void initializare(){
		vec.assign(n+1,0);
		heap.assign(2*n+n,0);
		poz.assign(n+1,0);
		for(int i = 0;i <= n; ++i) t.push_back(1<<12);
		t[1] = 0;
	}	
	void citire(){
		scan(n); scan(m);
		vecini[0].assign(n+1,d);
		vecini[1].assign(n+1,d);
		for(register int i = 0;i < m; ++i) {
			scan(x); scan(y); scan(z);
			vecini[0][x].push_back(make_pair(y,z));
			vecini[0][y].push_back(make_pair(x,z));
		}
	}
	int prim(int xx){
		cost=0;
		initializare();
		insertAPM(1);
		for(register int i = 2;i<=n; ++i)
			insertHEAP(i);
		for(register int i = 1;i < n; ++i){
			int x = peekHEAP();
			insertAPM( x );
			cost += t[x];
			vecini[(xx+1)%2][x].push_back( make_pair(vec[x] , t[x]) );
			vecini[(xx+1)%2][vec[x]].push_back( make_pair(x , t[x]) );
			for(unsigned j = 0;j < vecini[xx%2][x].size(); ++j){
				int nod = vecini[xx%2][x][j].first;
				if (poz[nod]) pop(poz[nod]);
			}
		}
		vecini[xx%2].clear();
		vecini[xx%2].assign(n+1,d);
		return cost;
	}
};
int main(){
	freopen("apm.in","rt",stdin);
	freopen("apm.out","wt",stdout);
	Arbore A;
	printf("%d\n",A.prim(0));
	
	return 0;
}