Cod sursa(job #67500)

Utilizator raula_sanChis Raoul raula_san Data 25 iunie 2007 10:38:46
Problema Sate Scor 0
Compilator cpp Status done
Runda preONI 2007, Runda Finala, Clasa a 10-a Marime 2.72 kb
#include <cstdio>

#define MAX_N 30001

int N, M, X, Y, RET;
int Use[MAX_N];

struct nod
{
       int nd, c;
       nod *next;
} *L[MAX_N], *E[MAX_N];

void Read();
void Solve();
void Print();

void Add(nod *&, nod*&, int, int);
void Deep(int);
void Df(int);

int main()
{
    Read();
    Solve();
    Print();
    
    return 0;
}

void Read()
{
     FILE *f = fopen("sate.in", "rt");
     int i, a, b, c;
     
     for(fscanf(f, "%d %d %d %d", &N, &M, &X, &Y), i=1; i<=M; ++i)
     {
                   fscanf(f, "%d %d %d", &a, &b, &c);
                   Add(L[a], E[a], b, c);
                   Add(L[b], E[b], a, c);
     }
     
     fclose(f);
}

void Solve()
{
     int i;
     
     for(i=1; i<=N; ++i)
              if(!Use[i])
                         Deep(i);

     for(i=1; i<=N; ++i)
              Use[i] = 0;
     
     Df(X);
}

void Print()
{
     FILE *g = fopen("sate.out", "wt");
     
     fprintf(g, "%d", RET);
     
     fclose(g);
}

void Add(nod *&L, nod*&E, int nd, int c)
{
     nod *p = new nod;
     p -> nd = nd;
     p -> c = c;
     p -> next = NULL;

     if(L == NULL)
          E = L = p;

     else
     {
         E -> next = p;
         E = p;
     }
}

void Deep(int nd)
{
     Use[nd] = 1;
     
     nod *g = L[nd];
     
     int i, j, k;
     
     i = nd;
     while(g)
     {
	     if(!Use[g->nd])
	     {
			    j = g -> nd;
			    nod *h = L[g->nd];

			    while(h)
			    {
				if(h -> nd != nd)
				{
				    k = h -> nd;

				    if(j > i && j < k)
				    {
					 Add(L[i], E[i], k, g -> c + h -> c);
					 Add(L[k], E[k], i, g -> c + h -> c);
				    }

				    if(k > i && k < j)
				    {
					 Add(L[i], E[i], k, g -> c - h -> c);
					 Add(L[k], E[k], i, g -> c - h -> c);
				    }

				    if(i > j && i < k)
				    {
					 Add(L[i], E[i], k, h -> c - g -> c);
					 Add(L[k], E[k], i, h -> c - g -> c);
				    }
				}

				h = h -> next;
			    }

			    Deep(g -> nd);
	     }

             g = g -> next;
     }
}

void Df(int nd)
{
     int new_node, c;

     Use[X] = 1;
     new_node = c = 0;

     while(new_node != Y)
     {
	 nod *g = L[nd];
	 new_node = N + 1;
	 c = 0;

	 while(g)
	 {
             if(g -> nd < new_node && g -> nd > nd && !Use[g->nd])
             {
                  new_node = g -> nd;
                  c = g -> c;
             }
             else if(g -> nd == Y)
             {
                  new_node = Y;
                  c = g -> c;
                  break;
             }
             
             g = g -> next;
         }
         
         Use[new_node] = 1;
	     RET += c;
	     nd = new_node;
     }
}