//Algoritmul lui Kruskal de determinare a unui APM

#include <stdio.h>
#define Mmax 4500
#define Nmax 100

int n,m;
// n reprezinta numarul de noduri iar m numarul de muchii din graful G

struct muchie
      {
       double cst;
       int x,y;
      } L[Mmax], Lfin[Nmax-1];
//L este o un vector de structuri de forma x,y,c ce reprezinta muchiile din garf
//x,y - nodurile extremitati ale muchiei
// c - costul muchiei
//Lfin reprezinta lista cu muchiile finale

int CompCon[Nmax];
double Cost;

void read(void); /* citeste datele de intrare in structura data in enunt */
void init(void); /* initializeaza vectorul ce tine evidenta componentelor conexe */
void CombHeap(int ,int); /* combina doua heap-uri */
void CreareHeap(void); /* creeaza un heap (in acest caz un MinHeap */
void ExtractHeap(int); /* extrage elementul din radacina heap-ului (elementul minim) */
void kruskal(void); /* realizeaza algoritmul lui Kruskal cu implementare de heap-uri */
void calculate_cost(void); /*calculeaza costul final al arborelui partial de cost minim 
insumand costurile muchiilor selectate */
void write(void); /* afiseaza in fisierul de iesire costul arborelui partial de cost 
minim si muchiile selectate ce formeaza acest arbore */

void read(void)
{
  FILE *f;
  int i;
  double aux;
  f = fopen("apm.in", "rt");

  fscanf(f,"%d\n",&n);
  fscanf(f,"%d\n",&m);

  for (i=0; i<m; i++)
       {
         fscanf (f,"%d %d",&L[i].x,&L[i].y);
         fscanf (f,"%lf", &aux);
         L[i].cst = aux;
         L[i].x--; L[i].y--;
       }
  fclose(f);
}

void init(void)
{
  int i;
  for (i=0; i<n; i++) CompCon[i] = i+1;
  }

void CombHeap(int i, int n)
{
  int fiu, tata;
  struct muchie aux;
  tata = i; fiu = 2*i;
  while (fiu<n)
       {
        if (fiu<n-1)
              fiu = L[fiu].cst<L[fiu+1].cst?fiu:fiu+1;
        if (L[tata].cst>L[fiu].cst)
              {
                aux = L[tata]; L[tata] = L[fiu]; L[fiu] = aux;
                tata = fiu; fiu *= 2;
              }
          else break;
       }
}

void CreareHeap(void)
{
  int i;
  for (i = m/2 - 1; i>=0; i--)
       CombHeap(i,m);
}

void ExtractHeap(int n)
{
  int tata,fiu;
  struct muchie aux;
  tata = 1; fiu = 2;
  L[tata] = L[n];
         
  if (fiu<n)
   do
       {
         if (fiu+1<n && L[fiu+1].cst<L[fiu].cst) fiu++;
         if (L[tata].cst<L[fiu].cst)
                {
                  aux = L[tata];
                  L[tata] = L[fiu];
                  L[fiu] = aux;
                  tata = fiu;
                  fiu *= 2;
                }
           else break;
       }
   while (fiu<n);
}

void kruskal(void)
{
  int i, j, k;
  CreareHeap();
  for (i=0, j=0; i<m && j<n; i++)
       {
         if (CompCon[L[i].x]!=CompCon[L[i].y])
               {
                 Lfin[j++] = L[i];
                 for (k=0; k<n; k++)
                        if (CompCon[k] == CompCon[L[i].x])
                                CompCon[k] = CompCon[L[i].y];
               }
               ExtractHeap(n-j+1);
       }
}

void calculate_cost()
{
  int i;
  for (i=0; i<n-1; i++)
       Cost += Lfin[i].cst;
}

void write(void)
{
  FILE *f;
  int i;
  f = fopen("apm.out","wt");

  fprintf(f,"%lf\n",Cost);

  for (i=0; i<n-1; i++)
        fprintf(f,"%d %d\n",Lfin[i].x+1,Lfin[i].y+1);

  fclose(f);
}


int main()
{
  read();
  init();
  kruskal();
  calculate_cost();
  write();
  return 0;
} 

Heap Interactiv :: Contact ::