Cod sursa(job #726851)

Utilizator paulbotabota paul paulbota Data 27 martie 2012 16:11:33
Problema Arbore partial de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2 kb
#include<fstream>
#include<algorithm>
#include<vector>
#define inf "apm.in"
#define outf "apm.out"
#define mp make_pair 
#define pb push_back
#define maxn 200010

using namespace std;

ifstream in(inf);
ofstream out(outf);

int N,M,sum,nr;
vector<pair<int,int> > vect[maxn],apm;
int h[maxn],poz[maxn],c[maxn],k,tata[maxn];
bool parc[maxn];

void read()
{
	int i;
	for(i=1;i<=M;i++)
	{
		int x,y,z;
		in>>x>>y>>z;
		vect[x].pb(mp(y,z));
		vect[y].pb(mp(x,z));
	}
}

void swap(int x,int y)
{
	int aux=h[x];
	h[x]=h[y];
	h[y]=aux;
}

void upheap(int i)
{
	while(i>1 && c[h[i/2]]>c[h[i]])
	{
		swap(i,i/2);
		poz[h[i]]=i;
		poz[h[i/2]]=i/2;
		i=i/2;
	}
}

void downheap(int i)
{
	int stg,dr,max=i;
	stg=2*i+1;
	dr=2*i;
	if(stg<=k && c[h[stg]]<c[h[i]])
		max=stg;
	if(dr<=k && c[h[dr]]<c[h[max]])
		max=dr;
	if(max!=i)
	{
		swap(max,i);
		poz[h[max]]=max;
		poz[h[i]]=i;
		upheap(max);
	}
}

int main()
{
	in>>N>>M;
	read();
	int i;
	for(i=0;i<vect[1].size();i++)
	{
		h[++k]=vect[1][i].first;
		c[h[k]]=vect[1][i].second;
		tata[h[k]]=1;
		poz[h[k]]=k;
		downheap(1);
	}
	parc[1]=true;
	tata[h[1]]=1;
	while(k)
	{
		if(parc[h[1]]==true)
		{
			swap(1,k);
			poz[h[1]]=1;
			poz[h[k]]=0;
			k--;
			downheap(1);
			continue;
		}
		int nod=h[1];
		sum=sum+c[h[1]];
		parc[h[1]]=true;
		nr++;
		apm.pb(mp(tata[nod],nod));
		swap(1,k);
		poz[h[1]]=1;
		poz[h[k]]=0;
		k--;
		downheap(1);
		for(i=0;i<vect[nod].size();i++)
		{
			int V=vect[nod][i].first;
			int cost=vect[nod][i].second;			
			if(parc[V]==false)
			{
				if(poz[V]!=0)
				{
					if(c[h[poz[V]]]<cost)
						continue;
					else
					{
						c[h[poz[V]]]=cost;
						tata[h[poz[V]]]=nod;
						swap(poz[V],k);
						upheap(k);
						continue;
					}
				}
			h[++k]=V;
			c[V]=cost;
		    tata[V]=nod;
			poz[V]=k;
			upheap(k);
			}
		}
	}
	out<<sum<<"\n"<<nr<<"\n";
	for(i=0;i<apm.size();i++)
		out<<apm[i].first<<" "<<apm[i].second<<"\n";
	return 0;
}