Cod sursa(job #690216)

Utilizator FERI24Forrai Francisc FERI24 Data 25 februarie 2012 13:28:02
Problema Algoritmul lui Dijkstra Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.37 kb
/*---Catun--
Intr-un regat feudal exista mai multe asezari omenesti, numerotate de la 1 la N, intre care sunt construite drumuri de diverse lungimi. Dintre aceste asezari, o parte sunt fortarete, iar restul sunt simple catune. Fiecare fortareata trebuie sa aprovizioneze trupele stationate in ea, deci are nevoie de feude. In calitate de mare sfetnic al monarhului, vi se cere sa indicati feudele aservite fiecarei fortarete, respectiv toate acele catune care se afla mai aproape de fortareata in discutie decat de oricare alta. Daca un catun este la distanta egala de doua fortarete, se va considera ca apartine fortaretei cu numarul de identificare minim.

Cerinta
Sa se determine pentru fiecare catun carei fortarete apartine.

Date de Intrare
In fisierul de intrare catun.in se vor afla numarele N, M, K, indicand, in aceasta ordine, numarul de asezari, numarul de drumuri si numarul de fortarete. Cea de a doua linie a fisierului va contine K numere naturale distincte indicand numerele de ordine ale fortaretelor. Pe urmatoarele M linii, pana la sfarsitul fisierului, se vor gasi triplete de forma (x y z), semnificand faptul ca exista un drum bidirectional intre asezarile x si y de lungime z, exprimata in unitatea de masura pentru lungimi a Evului Mediu.

Date de Iesire
Fisierul de iesire catun.out va contine o singura linie pe care se afla N numere naturale, al i-lea numar fiind 0, daca asezarea a i-a este o fortareata sau este un catun de la care nu se poate ajunge la nici o fortareata din cele K, sau numarul fortaretei de care se leaga asezarea a i-a, in caz contrar.

Restrictii si precizari
1 = K = N = 36 000
1 = M = 72 000
Intre oricare doua asezari exista maxim un drum*/

#include <fstream>
#include <queue>
#include <vector>
#include <utility>
#define INF 0x7fffffff

using namespace std;

typedef pair <int, int> edge;

int main()
{
    int N, M, K;
    ifstream in("catun.in");
    in >> N >> M >> K;
    pair <bool, vector <edge> > graph[36001];
    int dis[36001];
    int fort[36001], min[36001];
    priority_queue <edge, vector<edge>, greater<edge> > S;
    for(int i = 1; i <= N; ++i)
    {
        min[i] = INF;
        dis[i] = INF;
    }
    while(K--)
    {
        int w;
        in >> w;
        graph[w].first = true;
        S.push(make_pair(0,w));
        dis[w] = 0;
        fort[w] = w;
    }
    for(int i = 0, a, b, c; i < M; ++i)
    {
        in >> a >> b >> c;
        graph[a].second.push_back(make_pair(c,b));
        graph[b].second.push_back(make_pair(c,a));
    }
    in.close();
    while (!S.empty())
    {
        int no = S.top().second;
        int diw = S.top().first;
        S.pop();
        if(diw!=dis[no])
            continue;
        for(int i = 0; i < graph[no].second.size(); ++i)
        {
            if(graph[no].second[i].first + dis[no] < dis[graph[no].second[i].second])
            {
                fort[graph[no].second[i].second] = fort[no];
                dis[graph[no].second[i].second] = graph[no].second[i].first + dis[no];
                S.push(make_pair(dis[graph[no].second[i].second], graph[no].second[i].second));
            }
        }
    }
    ofstream out("catun.out");
    for(int i = 1; i <= N; ++i)
    {
        if(graph[i].first)
        {
            out << "0 ";
            continue;
        }
        out << fort[i] << " ";
    }
    out.close();
    return 0;
}