Cod sursa(job #673133)

Utilizator S7012MYPetru Trimbitas S7012MY Data 3 februarie 2012 22:21:35
Problema Floyd-Warshall/Roy-Floyd Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.4 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <iostream>
#define DN 65
#define MULT (1<<30)-1
#define mat dmin
using namespace std;

int n,m,t,st[DN],dmin[DN][DN],a[DN*DN],b[DN*DN],c[DN*DN],ind[DN*DN],sz,pre[DN],spec[DN],tc=MULT;
vector<int> nod;

void rf() {
    int i,j,k;
    for(i=1; i<=n; i++)
        for(j=1; j<=n; j++)
            for(k=1; k<=n; k++)
                if (j==k) mat[j][k]=0;
                else mat[j][k]=min(mat[j][k],mat[j][i]+mat[i][k]);
}

int find(int n) {
    if(pre[n]==n) return n;
    pre[n]=find(pre[n]);
    return pre[n];
}

void unite(int i, int j) {
    pre[find(i)]=find(j);
}

bool cmp(const int &i, const int &j) {
    return c[i]<c[j];
}

int apm(int niv) {
    sz=0;
    //cout<<'\n';
    for(int i=1; i<=niv; ++i) for(int j=1; j<=niv; ++j)
        if(i!=j && dmin[nod[st[i]]][nod[st[j]]]) {
            a[++sz]=nod[st[i]];
            b[sz]=nod[st[j]];
            c[sz]=dmin[nod[st[i]]][nod[st[j]]];
           // cout<<a[sz]<<' '<<b[sz]<<' '<<c[sz]<<'\n';
        }
    int tcc=0,nrc=0;
    for(int i=1; i<=sz; ++i) ind[i]=i;
    for(int i=1; i<=n; ++i) pre[i]=i;
    sort(ind+1,ind+sz+1,cmp);
    for(int i=1; i<=sz; ++i)
        if(find(a[ind[i]])!=find(b[ind[i]])){
           // cout<<a[ind[i]]<<' '<<b[ind[i]]<<'\n';
            tcc+=c[ind[i]];
            if(tcc>tc) return MULT;
            unite(a[ind[i]],b[ind[i]]);
            ++nrc;
        }
  //  cout<<nrc<<' ';
    if(nrc<niv-1) return MULT;
    return tcc;
}

void back(int niv) {//generez submultimi
   // cout<<niv<<' ';
    if(niv>=2*t-1 || niv>n) return;
    tc=min(tc,apm(niv));
   // cout<<niv<<' '<<tc<<'\n';
    for(int i=st[niv]+1; i<n; ++i) {
        st[niv+1]=i;
        back(niv+1);
    }
}

int main()
{
    ifstream f("subarbore.in");
    ofstream g("subarbore.out");
    f>>n>>m;
    for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) dmin[i][j]=MULT;
    for(int i=1; i<=m; ++i) {
        int a,b,c;
        f>>a>>b>>c;
        if(dmin[a][b]) dmin[a][b]=dmin[b][a]=min(dmin[a][b],c);
        else dmin[a][b]=dmin[b][a]=c;
    }
    rf();
    /*for(int i=1; i<=n; ++i) {
        for(int j=1; j<=n; ++j) cout<<dmin[i][j]<<' ';
        cout<<'\n';
    }*/
    f>>t;
    nod.push_back(0);
    for(int i=1; i<=t; ++i) {
        int a;
        f>>a;
        spec[a]=1;
        nod.push_back(a);
        st[i]=i;
    }
    for(int i=1; i<=n; ++i) if(!spec[i]) nod.push_back(i);


    back(t);
    g<<tc;
    return 0;
}