Cod sursa(job #891766)

Utilizator paulbotabota paul paulbota Data 25 februarie 2013 19:42:24
Problema Arbore partial de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.85 kb
#include <cstdio>
#include <algorithm>
#include<vector>
#define mp make_pair
#define pb push_back
#define MAXN 200010
#define INF 1<<30
using namespace std;




vector<pair<int,int> > vect[MAXN],apm;
int n,m,sum,h[2*MAXN+100],poz[MAXN],k,tata[MAXN],c[MAXN];

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

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

void downheap(int i)
{
	int stg,dr,max=i;
	stg=2*i;
	dr=2*i+1;
	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);
		downheap(max);
	}
}

void insert_heap(int i)
{
	h[++k]=i;
	poz[i]=k;
	upheap(k);
}

int extract_min()
{
	int root=h[1];
	swap(1,k);
	k--;
	downheap(1);
	poz[root]=0;
	return root;
}


inline void read()
{
    freopen("apm.in","r",stdin);
    freopen("apm.out","w",stdout);
    int x,y,z;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %d",&x,&y,&z);
        vect[x].pb(mp(y,z));
		vect[y].pb(mp(x,z));
    }
}


void insert(int i)
{
	for(int j=0;j<vect[i].size();j++)
	{
		int nod=vect[i][j].first;
		int cost=vect[i][j].second;
		c[nod]=min(c[nod],cost);
		if(c[nod]==cost) tata[nod]=i;
	}
}

int main()
{
    read();
    int i;
    for(i=1;i<=n;i++)
        c[i]=INF;
    c[1]=0;
    insert(1);
    for(i=2;i<=n;i++)
    {
        insert_heap(i);
    }

   for(i=1;i<n;i++)
	{
		int nod=extract_min();
		insert(nod);
		sum+=c[nod];
		apm.pb(mp(tata[nod],nod));
		for(int j=0;j<vect[nod].size();j++)
		{
			int vertex=vect[nod][j].first;
			if(poz[vertex]) upheap(poz[vertex]);
		}
	}
    printf("%d\n%d\n",sum,n-1);
   for(i=0;i<apm.size();i++)
        printf("%d %d\n",apm[i].first,apm[i].second);
    return 0;
}