Cod sursa(job #766924)

Utilizator danalex97Dan H Alexandru danalex97 Data 12 iulie 2012 14:50:26
Problema Arbore partial de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.15 kb
// O(M lg N)
// punem in heap noduri
// e nevoie de vectorul poz pentru a nu pastra N-uri
// Prim mai are si rezolvare de complexitate O(N^2)

#include <fstream>
#include <vector>
using namespace std;

const int Nmax = 200011;
const int Mmax = 400011;

#define val first
#define v1 second.first
#define v2 second.second

typedef pair<int, pair<int,int> > Grupe;
typedef Grupe Heap[Nmax];

Grupe Null;

int Apm[Nmax];
int N,M,Size,Ans;
Heap H;
int Poz[Nmax];
vector< pair<int,int> > A[Nmax];
vector< pair<int,int> > Aux;
vector< pair<int,int> > Sol;

ifstream F("apm.in");
ofstream G("apm.out");

void DownHeap(Heap a, int n , int k)
{
	int p;
	p=1;
	while (p)
	{
		p=0;
        if (2*k<=n) 
		{
            p=2*k; 
            if ( (2*k+1<=n) && (a[2*k+1].val<a[2*k].val) ) 
                p++; 
            if (a[p].val >= a[k].val)
                p=0;
        }
        if (p) 
		{
			swap(Poz[a[k].v2],Poz[a[p].v2]);
            swap(a[k].val,a[p].val);
            swap(a[k].v1,a[p].v1);
            swap(a[k].v2,a[p].v2);
			k=p;
        }
	}
}

void UpHeap(Heap a, int n, int k) 
{
	int p=a[k].val;
	int p3=a[k].v1;
	int p4=a[k].v2;
	while ( (k>1) && (p<a[k/2].val) ) 
	{
		swap(Poz[p4],Poz[a[k/2].v2]);
		a[k].val=a[k/2].val;
		a[k].v1=a[k/2].v1;
		a[k].v2=a[k/2].v2;
		k=k/2;
	}
   a[k].val=p;
   a[k].v1=p3;
   a[k].v2=p4;
}

void Earse(Heap a, int& n, int k) 
{
    swap(Poz[a[k].v2],Poz[a[n].v2]); 
    swap(a[k].val,a[n].val); 
    swap(a[k].v1,a[n].v1); 
    swap(a[k].v2,a[n].v2); 
	
	int ok=1; if ( k==n ) ok=0;
	
	n--;
	Poz[a[n+1].v2]=0;
	a[n+1]=Null;
    
	if ( ok && (k>1) && (a[k].val<a[k/2].val) ) 
        UpHeap(a,n,k); 
	else                          
        DownHeap(a,n,k);
}

void Insert(Heap a, int& n, int one,int two , int three) 
{
    a[++n].val=one;
    a[n].v1=two;
    a[n].v2=three;
	
	Poz[a[n].v2]=n;
    UpHeap(a, n, n); 
}

void Insert_Neighbour( int nod )
{
	Apm[nod]=1;
	
	while ( A[nod].size() )
	{
		Aux.push_back( A[nod].back() );
		if ( !Apm[ A[nod].back().first ] )
		{
			if ( ! Poz[ A[nod].back().first ] )
				Insert(H,Size, A[nod].back().second , nod , A[nod].back().first  );
			else
				if ( A[nod].back().second < H[ Poz[ A[nod].back().first ] ].val) 
				{
					Earse(H,Size,Poz[ A[nod].back().first ]);
					Insert(H,Size, A[nod].back().second , nod , A[nod].back().first  );
				}
		}
		A[nod].pop_back();
	}
	while ( Aux.size() )
	{
		A[nod].push_back( Aux.back() );
		Aux.pop_back();
	}
}

int main()
{
	F>>N>>M;
	for (int i=1;i<=M;++i)
	{
		int x,y,cost;
		F>>x>>y>>cost;
		A[x].push_back( make_pair( y , cost ) );
		A[y].push_back( make_pair( x , cost ) );
	}
	
	Insert_Neighbour( 1 );
	
	for (int i=1;i<N;++i)
	{
		while ( Apm[ H[1].v2 ] ) 
			Earse( H, Size , 1 );
		
		int value = H[1].val ;
		int start = H[1].v1 ;
		int endin = H[1].v2 ;
		
		Earse( H, Size , 1 );
		Insert_Neighbour( endin );
		
		Sol.push_back( make_pair(start,endin) );
		Ans+= value;
	}
	
	G<<Ans<<'\n';
	for ( G<<Sol.size()<<'\n' ; Sol.size() ; Sol.pop_back() )
		G<<Sol.back().first<<' '<<Sol.back().second<<'\n';
}