Cod sursa(job #1119620)

Utilizator vladstoickvladstoick vladstoick Data 24 februarie 2014 18:55:38
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.59 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");

const int N = 2001;
const int K = 20;
const int INF = 100000 * N;
class Muchie{
    public:
        int destinatie, valoare;
        Muchie(int,int);
};

Muchie::Muchie(int a, int b){
    destinatie = a;
    valoare = b;
}

vector <Muchie> muchii[N];

int graf2[K][K];

vector <int> obligatorii;

int n , m , k;
int nodAdaugat;


void bellmanford(int varf){

    queue<int> coada;
    vector<int> nrTreceri(n+1);
    vector<int> cost(n+1);
    for(int i=1;i<=n;i++){
        cost[i]=INF;
    }
    cost[varf] = 0;
    coada.push(varf);
    while(!coada.empty()){
        int old_varf = coada.front();
        int old_cost = cost[old_varf];
        coada.pop();
        for(vector<Muchie>::iterator it = muchii[old_varf].begin(); it < muchii[old_varf].end(); it++){
            int new_varf = it->destinatie;
            int new_cost = it->valoare;
            if(cost[new_varf] > new_cost + old_cost){
                nrTreceri[new_varf]++;
                if(nrTreceri[new_varf]==n){
                    return;
                }
                coada.push(new_varf);
                cost[new_varf] = new_cost + old_cost;
            }
        }
    }
    if(varf!=1){
        graf2[nodAdaugat][0] = cost[1];
    }
    for(int i=0;i<obligatorii.size();i++){
        if(obligatorii[i]!=varf){
            graf2[nodAdaugat][i+1] = cost[obligatorii[i]];
        }
    }
    if(varf!=n){
        graf2[nodAdaugat][obligatorii.size()+1] = cost[n];
    }
    nodAdaugat++;

}

int d[K][K];

void detCiclu(){
    int nrVarfuri = obligatorii.size()+2;
    for(int i=1;i<=nrVarfuri;i++){
        d[i][1] = INF;
    }
    int nrPerm = (1<<nrVarfuri);
    for(int i=3;i<=nrPerm;i+=2){
        d[i][0]=INF;
        for(int j=1;j<nrVarfuri;j++){
            d[i][j] = INF ;
            int j2 = (1<<j);
            if( i & j2 ) {
                int iprim = i ^ j2 ;
                for(int k = 0 ; k <nrVarfuri ; k++ ){
                    int k2 = (1<<k);
                    if(graf2[k][j]!=0 && (iprim & k2) && j!=k ){
                        d[i][j] = min ( d[i][j], d[iprim][k] + graf2[k][j] );
                    }
                }
            }
        }
    }

    int rez = INF;
    for(int i=1;i<nrVarfuri;i++){
        if(graf2[i][0]!=0){
            rez = min(rez, d[nrPerm][i] + graf2[i][0]);
        }
    }
    out<<rez<<"\n";
}

void afisDemoGraf2(){
    out<<"GRAF2 start\n";
    int nrVarfuri = obligatorii.size()+2;
    for(int i=1;i<=nrVarfuri;i++){
        for(int j=1;j<=nrVarfuri;j++){
            out<<graf2[i][j]<<" ";
        }
        out<<"\n";
    }
    out<<"GRAF2 end\n";
}

void afisDemoCiclu()
{
    out<<"Ciclu start\n";
    int nrVarfuri = obligatorii.size()+2;
    for(int i=0;i<nrVarfuri;i++){
        for(int j=0;j<nrVarfuri;j++){
            out<<d[i][j]<<" ";
        }
        out<<"\n";
    }
    out<<"Ciclu end\n";

}

int main()
{
    in>>n>>m;
    in>>k;
    for(int i=1;i<=k;i++){
        int x; in>>x;
        obligatorii.push_back(x);
    }
    for(int i=1;i<=m;i++){
        int x,y,v;
        in>>x>>y>>v;
        muchii[x].push_back(Muchie(y,v));
        muchii[y].push_back(Muchie(x,v));
    }



    bellmanford(1);
    for(vector<int>::iterator it = obligatorii.begin(); it < obligatorii.end(); it++){
        bellmanford(*it);
    }
    bellmanford(n);
    afisDemoGraf2();

    detCiclu();
    afisDemoCiclu();

    return 0;
}