Cod sursa(job #445072)

Utilizator Bogdan_CCebere Bogdan Bogdan_C Data 22 aprilie 2010 18:03:19
Problema Arbore partial de cost minim Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.7 kb
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#define FIN "apm.in"
#define FOUT "apm.out"
#define NMAX 200002
#define MMAX 400002
using namespace std;


struct G
{
	int e;
	int cost;
	int poz;
	G* next;
};
typedef G* g;
g gr[NMAX];
int aux,t,cost_t,cost[MMAX],m,n,h[NMAX],viz[NMAX],poz_heap[NMAX],k,x,y,c,fiu;
pair<int,int> muchii[MMAX];
vector< pair<int,int> > apm;

void push(g &act,int x,int c,int poz)
{
	g ax=new G;
	ax->e=x;
	ax->cost=c;
	ax->poz=poz;
	ax->next=act;
	act=ax;
}

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

void upheap(int poz)
{
	while(poz>1)
	{
		t = poz>>1;
		if(cost[h[t]] > cost[h[poz]]) 
		{
			poz_heap[h[t]] = poz;
            poz_heap[h[poz]] = t;
            swap(poz,t);
            poz=t;
		}
		else poz=1;                                  
	}   
}

void downheap(int poz)
{
	while(poz <= k)
	{
		fiu = poz<<1;
		if(fiu <= k)
		{
			if(fiu+1<=k && cost[h[fiu]] > cost[h[fiu + 1]])
				fiu++;
		}
		else return; 
		if(cost[h[poz]]>cost[h[fiu]]) 
		{
			poz_heap[h[fiu]] = poz;
            poz_heap[h[poz]] = fiu;
            swap(poz,fiu);
            poz = fiu;;
		} 
		else poz = k+1;
	}
}     

void prim()
{
  int gasit,val,nod,contor=1;
  viz[1] = 1;
  for(g i=gr[1];i;i=i->next)
	  {
		  k++;
		  h[k] = i->poz;
          upheap(k);
	  }
	  while(contor <= n-1)
	  {
		  gasit=0;
		  while(!gasit && k)
		  {
			  val = h[1];
			  swap(1,k);
			  k--;
			  downheap(1);
			  if(!viz[muchii[val].first] || ! viz[muchii[val].second]) gasit=1;
		  }
		  cost_t += cost[val];
		  apm.push_back(muchii[val]);
		  contor++;
		  if(viz[muchii[val].first]==0) 
		  {
			  viz[muchii[val].first]=1;
              nod=muchii[val].first;
              for(g i=gr[nod];i;i=i->next) 
				  {
					  k++;
					  h[k]=i->poz;
					  upheap(k);
				  }
		  }     
		  if(viz[muchii[val].second]==0) 
		  {
			  viz[muchii[val].second]=1;
              nod=muchii[val].second;
              for(g i=gr[nod];i;i=i->next) 
				  {
					  k++;
                      h[k]=i->poz;
                      upheap(k);
				  }
		  }                                                                          
	  }   
}

int main()
{
    freopen(FIN,"r",stdin);
    freopen(FOUT,"w",stdout);
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++)
	{
		scanf("%d %d %d",&x,&y,&c);
		push(gr[x],y,c,i);
		push(gr[y],x,c,i);
        muchii[i]=make_pair(x,y);
        cost[i]=c; 
	}
	prim();    
	printf("%d\n%d\n",cost_t,n-1);
	vector<  pair<int,int> >::iterator it;
	for(it=apm.begin();it!=apm.end();it++)
	{
		printf("%d %d\n",it->first,it->second);
	}
    return 0;
}