Rezolvare completă PbInfo #1955 plimbare1

Cerința

Personajul acestei probleme este Lucian. Lucian locuiește în tara lui Verde Împărat, această tară având n orașe, numerotate de la 1 la n. Cum în orice poveste cu împărați există și o prințesă, și în problema noastră avem o prințesă, să o numim Maria. Maria este fiica lui Verde Împărat și în același timp prietena lui Lucian.

În tara lui Verde Împărat se apropie sărbătorile, iar ca să fie sigur de un nou mandat, împăratul a promis că va repara câteva drumuri, astfel încât să se poată ajunge din orice oraș, în oricare alt oraș, mergând doar pe drumuri care nu sunt stricate. Fiecare drum care este stricat are un cost de reparație , și având în vedere că se apropie sărbătorile, Împăratul ar vrea să repare drumurile optim, astfel încât să obțină un cost cât mai mic. Știind că Lucian vrea să-i ceară mâna Mariei, Împăratul i-a încredințat lui Lucian această sarcină, iar în cazul în care nu va putea să o îndeplinească îl va izgoni din tară. Lucian nu a fost prezent mai deloc la orele de algoritmică din liceu și vă cere vouă ajutorul pentru această problema complicată. Având la dispoziție lista drumurilor, precum și lista drumurilor stricate, voi trebuie să-i spuneți lui Lucian care este suma minimă pe care trebuie să o folosească pentru a se putea ajunge din orice oraș în oricare alt oraș.

Date de intrare

Fișierul plimbare1.in conține pe prima linie două numere N și M, reprezentând numărul de orașe și numărul de drumuri din tara lui Verde Împărat. Pe următoarele M linii vor fi descrise drumurile sub următoarea formă:

  • 1 a b – există un drum între a și b;
  • 2 a b c – există un drum între a și b care poate fi reparat cu costul c.

Date de ieșire

Fișierul plimbare1.out conține pe prima linie un număr S, reprezentând costul minim al reparării drumurilor, pentru a se putea ajunge din orice oraș în oricare alt oraș.

Restricții și precizări

1 ≤ N ≤ 100.000
1 ≤ M ≤ 120.000
1 ≤ c ≤ 250 – număr natural
• drumurile sunt bidirecționale


Exemplu

plimbare1.in

5 5
1 1 2 
1 3 4
2 2 3 6
2 3 5 9
2 4 5 6

plimbare1.out

12

Explicație

Observăm că nu putem ajunge în orașul 3 din orașul 1, sau din orașul 2 în orașul 3, de aceea trebuie să reparăm un drum, astfel încât să fie posibil să ajungem în orașul 3. Astfel, selectam drumul 2 3 cu costul 6. După ce am reparat acest drum observăm că nu putem ajunge în orașul 5. Avem două drumuri posibile de reparat pentru a ajunge apoi în orașul 5 , 3 5 cu costul 9 si 4 5 cu costul 6. Îl vom alege pe cel mai mic (cel cu costul 6), astfel după ce reparăm și acest drum putem ajunge din orice oraș în oricare altul.

Cum e corect?

cout < "As la info"; cout << "As la info"; cout >> "As la info";

Felicitări! Poți mai mult?

Avem sute de probleme pentru tine, fiecare cu explicații ușor de înțeles.

Greșit, dar nu-i bai!

Antrenează-te cu sutele de probleme pe care ți le-am pregătit. Îți explicăm fiecare problemă în parte.

Rezolvare

Iată rezolvarea de 100 de puncte pentru problema plimbare1:

#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#define dim 120004

using namespace std;

ifstream f ("plimbare1.in");
ofstream g ("plimbare1.out");

struct filip
{
    int x,y,cost;
} v[dim];

int l[dim],poz[dim],c;

bool cmp(int a,int b)
{
    return v[a].cost < v[b].cost;
}

int grupa(int x)
{
    if(l[x] == x)
        return x;
    l[x] = grupa(l[x]);
    return l[x];
}

void uneste(int x,int y)
{
    l[grupa(x)] = grupa(y);
}

int main()
{
    int n,m,i,k = 0,ct = 0,xx,yy,caz,mm = 0;
    f >> n >> m;
    for(i = 1; i <= n; i++)
        l[i] = i;
    for(i = 1; i <= m; i++)
    {
        f >> caz >> xx >> yy;
        switch(caz)
        {
        case 1:
            uneste(xx,yy);
            break;
        case 2:
            f >> c;
            v[++mm].x = xx;
            v[mm].y = yy;
            v[mm].cost = c;
        }
    }
    for(i = 1; i <= mm; i++)
        poz[i] = i;
    sort(poz + 1,poz + mm + 1,cmp);
    for(i = 1; i <= mm; i++)
        if(grupa(v[poz[i]].x) != grupa(v[poz[i]].y))
        {
            ct += v[poz[i]].cost;
            uneste(v[poz[i]].x,v[poz[i]].y);
        }
    g << ct << '\n';
    return 0;
}

Atenție

Enunțurile afișate pe această pagină aparțin exclusiv site-ului PbInfo. Astfel, pentru ștergerea conținutului, puteți să ne contactați la adresa Adresa de email.

Rezolvarea problemei #1955 plimbare1

Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #1955 plimbare1 de pe PbInfo.ro. Atenție: nu încurajăm copiatul codului! Totuși, credem cu tărie că analizarea unei soluții corecte este o metodă foarte ușoară de a învăța informatică, astfel că oferim sursele pentru peste 1500 de probleme de pe platforma PbInfo.ro.

Pentru rezolvări PbInfo de la peste 1500 de probleme, vă invităm să intrați pe site-ul nostru!