Cod sursa(job #1456120)

Utilizator manciu_ionIon Manciu manciu_ion Data 29 iunie 2015 20:15:52
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 13.39 kb

/// Punncte = 100, TIME = 0.3
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>

#define nMax 2002

using namespace std;

const int inf = 0x3f3f3f3f;

struct Nod
{
    int varf;
    int cod;
    int cost;
    Nod(int vf = 0, int cd = 0, int c = 0)
    {
        varf = vf;
        cod = cd;
        cost = c;
    }
};

queue < Nod > q;
int dp[16][nMax];
int ph[nMax], h[nMax];
int poz[nMax], p[16], p2[17];
vector < pair< int,int > > v[nMax];
int c[17], uz[17], cost[16][1<<17];
int k, n, m, K, ax, cx;
int optim = inf, best;

void ReadData();
void PrintSol();
void solve();
void combTop(int dp[nMax], int c);
void combDown(int dp[nMax], int f);
void push(int dp[nMax], int x);
int pop(int dp[nMax]);
void dijkstra(int dp[nMax], int x);
void GenPerm(int t, int cd);
void Find();

int main()
{
    freopen("ubuntzei.in", "rt", stdin);
    freopen("ubuntzei.out", "wt", stdout);

    ReadData();
    solve();
    Find();
    PrintSol();

    fclose(stdin);
    fclose(stdout);
    return 0;
}

void PrintSol()
{
    int mask = (1 << K) - 1;
    if (K == 0) optim = dp[0][n];
    for (int i = 1; i <= K; ++i)
       if (cost[i][mask] + dp[i][n] < optim)
       optim = cost[i][mask] + dp[i][n];
    printf("%d\n", optim);
}

void Find()
{
    memset(cost, inf, sizeof(cost));
    int i, x, cx, cd, dx, rx, cs;
    cost[0][0] = 0;
    for (q.push(Nod(0, 0, 0)); !q.empty(); q.pop())
    {
        x = q.front().varf;
        cd = q.front().cod;
        cs = q.front().cost;
        dx = cost[x][cd];

        if (cs > dx) continue;

        //printf("%d %d\n", x, cd);
        for (i = 1; i <= K; ++i)
           if (cost[poz[c[i]]][cx = cd | p2[i]] > (rx = dx + dp[x][c[i]]))
           {
               cost[poz[c[i]]][cx] = rx;
               q.push(Nod(poz[c[i]], cx, rx));
           }
    }
}

void combTop(int dp[nMax], int c) {
  int f = c>>1;
  while(f && dp[h[f]] > dp[h[c]]) {
    swap(h[f], h[c]);
    swap(ph[h[f]], ph[h[c]]);
    c = f, f >>= 1;
  }
}

void combDown(int dp[nMax], int f) {
  int c = f<<1;
  while(c <= k) {
    if(c < k && dp[h[c+1]] < dp[h[c]]) ++c;
    if(dp[h[c]] < dp[h[f]]) {
      swap(h[c], h[f]);
      swap(ph[h[c]], ph[h[f]]);
      f = c, c <<= 1;
    }
    else return;
  }
}

void push(int dp[nMax], int x) {
  //printf("push(%d)\n", x);
  h[++k] = x, ph[x] = k;
  combTop(dp, k);
}

int pop(int dp[nMax]) {
  int x = h[1];
  //printf("pop(%d)\n", x);
  h[1] = h[k--];
  if(k) ph[h[1]] = 1, combDown(dp, 1);
  return x;
}

void solve()
{
    for (int i = 0; i <= K; ++i) dijkstra(dp[i],c[i]);
    p2[1] = 1;
    for (int i = 2; i < 17; ++i) p2[i] = p2[i-1] << 1;
}

void dijkstra(int dp[nMax], int x) {

  //printf("dijkstra(%d)\n", x);

  for(int i = 1; i <= n; ++i)
    dp[i] = inf, ph[i] = 0;

  dp[x] = 0; push(dp, x);
  while(k) {
    x = pop(dp);
    //printf("%d %d\n", k, x);
    /// asa e mai rapid
    unsigned end = v[x].size();
    for(unsigned i = 0; i < end; ++i)
      if(dp[x] + v[x][i].second < dp[v[x][i].first]) {
        dp[v[x][i].first] = dp[x] + v[x][i].second;
        if(ph[v[x][i].first]) combTop(dp, ph[v[x][i].first]);
        else push(dp, v[x][i].first);
      }
  }
}

void ReadData()
{
    scanf("%d%d", &n, &m);
    scanf("%d", &K);
    int i, x, y, z;
    c[0] = 1;
    for (i = 1; i <= K; ++i)
    {
        scanf("%d", &c[i]);
        poz[c[i]] = i;
    }
    for (i = 0; i < m; ++i)
    {
        scanf("%d%d%d", &x, &y, &z);
        v[x].push_back(make_pair(y,z));
        v[y].push_back(make_pair(x,z));
    }
}

/*
/// Punncte = 75, TIME = tle (0.15)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>

#define nMax 2002

using namespace std;

const int inf = 0x3f3f3f3f;

struct Nod
{
    int varf;
    int cod;
    Nod(int vf = 0, int cd = 0)
    {
        varf = vf;
        cod = cd;
    }
};

queue < Nod > q;
int dp[16][nMax];
int ph[nMax], h[nMax];
int poz[nMax], p[16], p2[17];
vector < pair< int,int > > v[nMax];
int c[17], uz[17], cost[16][1<<17];
int k, n, m, K, ax, cx;
int optim = inf, best;

void ReadData();
void PrintSol();
void solve();
void combTop(int dp[nMax], int c);
void combDown(int dp[nMax], int f);
void push(int dp[nMax], int x);
int pop(int dp[nMax]);
void dijkstra(int dp[nMax], int x);
void GenPerm(int t, int cd);
void Find();

int main()
{
    freopen("ubuntzei.in", "rt", stdin);
    freopen("ubuntzei.out", "wt", stdout);

    ReadData();
    solve();
    Find();
    PrintSol();

    fclose(stdin);
    fclose(stdout);
    return 0;
}

void PrintSol()
{
    int mask = (1 << K) - 1;
    if (K == 0) optim = dp[0][n];
    for (int i = 1; i <= K; ++i)
       if (cost[i][mask] + dp[i][n] < optim)
       optim = cost[i][mask] + dp[i][n];
    printf("%d\n", optim);
}

void Find()
{
    memset(cost, inf, sizeof(cost));
    int i, x, cx, cd, dx, rx;
    cost[0][0] = 0;
    for (q.push(Nod(0, 0)); !q.empty(); q.pop())
    {
        x = q.front().varf;
        cd = q.front().cod;
        dx = cost[x][cd];
        //printf("%d %d\n", x, cd);
        for (i = 1; i <= K; ++i)
           if (cost[poz[c[i]]][cx = cd | p2[i]] > (rx = dx + dp[x][c[i]]))
           {
               cost[poz[c[i]]][cx] = rx;
               q.push(Nod(poz[c[i]], cx));
           }
    }
}

void combTop(int dp[nMax], int c) {
  int f = c>>1;
  while(f && dp[h[f]] > dp[h[c]]) {
    swap(h[f], h[c]);
    swap(ph[h[f]], ph[h[c]]);
    c = f, f >>= 1;
  }
}

void combDown(int dp[nMax], int f) {
  int c = f<<1;
  while(c <= k) {
    if(c < k && dp[h[c+1]] < dp[h[c]]) ++c;
    if(dp[h[c]] < dp[h[f]]) {
      swap(h[c], h[f]);
      swap(ph[h[c]], ph[h[f]]);
      f = c, c <<= 1;
    }
    else return;
  }
}

void push(int dp[nMax], int x) {
  //printf("push(%d)\n", x);
  h[++k] = x, ph[x] = k;
  combTop(dp, k);
}

int pop(int dp[nMax]) {
  int x = h[1];
  //printf("pop(%d)\n", x);
  h[1] = h[k--];
  if(k) ph[h[1]] = 1, combDown(dp, 1);
  return x;
}

void solve()
{
    for (int i = 0; i <= K; ++i) dijkstra(dp[i],c[i]);
    p2[1] = 1;
    for (int i = 2; i < 17; ++i) p2[i] = p2[i-1] << 1;
}

void dijkstra(int dp[nMax], int x) {

  //printf("dijkstra(%d)\n", x);

  for(int i = 1; i <= n; ++i)
    dp[i] = inf, ph[i] = 0;

  dp[x] = 0; push(dp, x);
  while(k) {
    x = pop(dp);
    //printf("%d %d\n", k, x);
    /// asa e mai rapid
    unsigned end = v[x].size();
    for(unsigned i = 0; i < end; ++i)
      if(dp[x] + v[x][i].second < dp[v[x][i].first]) {
        dp[v[x][i].first] = dp[x] + v[x][i].second;
        if(ph[v[x][i].first]) combTop(dp, ph[v[x][i].first]);
        else push(dp, v[x][i].first);
      }
  }
}

void ReadData()
{
    scanf("%d%d", &n, &m);
    scanf("%d", &K);
    int i, x, y, z;
    c[0] = 1;
    for (i = 1; i <= K; ++i)
    {
        scanf("%d", &c[i]);
        poz[c[i]] = i;
    }
    for (i = 0; i < m; ++i)
    {
        scanf("%d%d%d", &x, &y, &z);
        v[x].push_back(make_pair(y,z));
        v[y].push_back(make_pair(x,z));
    }
}
*/
/*
/// Punncte = 75, TIME = tle (0.39)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>

#define nMax 2002

using namespace std;

const int inf = 0x3f3f3f3f;

int dp[16][nMax];
int ph[nMax], h[nMax];
int poz[nMax], p[16], p2[17];
vector < pair< int,int > > v[nMax];
int c[17], uz[17], cost[16][1<<17];
int k, n, m, K, ax, cx;
int optim = inf, best;

void ReadData();
void PrintSol();
void solve();
void combTop(int dp[nMax], int c);
void combDown(int dp[nMax], int f);
void push(int dp[nMax], int x);
int pop(int dp[nMax]);
void dijkstra(int dp[nMax], int x);
void GenPerm(int t, int cd);

int main()
{
    freopen("15-ubuntzei.in", "rt", stdin);
    //freopen("ubuntzei.out", "wt", stdout);

    ReadData();
    solve();
    GenPerm(1, 0);
    PrintSol();

    fclose(stdin);
    fclose(stdout);
    return 0;
}

void PrintSol()
{
    printf("%d\n", optim);
}

void GenPerm(int t, int cd)
{
    if (t > K)
    {
        if (best+dp[p[K]][n] < optim) optim = best+dp[p[K]][n];
    }
    else
    for (int i = 1; i <= K; ++i)
       if (!uz[i] and best+dp[p[t-1]][c[i]] < cost[ax = poz[c[i]]][cx = cd | p2[ax]])
       {
           uz[i] = 1;
           p[t] = ax;
           best += dp[p[t-1]][c[i]];
           cost[p[t]][cx] = best;
           GenPerm(t+1, cx);
           uz[i] = 0;
           best -= dp[p[t-1]][c[i]];
       }
}

void combTop(int dp[nMax], int c) {
  int f = c>>1;
  while(f && dp[h[f]] > dp[h[c]]) {
    swap(h[f], h[c]);
    swap(ph[h[f]], ph[h[c]]);
    c = f, f >>= 1;
  }
}

void combDown(int dp[nMax], int f) {
  int c = f<<1;
  while(c <= k) {
    if(c < k && dp[h[c+1]] < dp[h[c]]) ++c;
    if(dp[h[c]] < dp[h[f]]) {
      swap(h[c], h[f]);
      swap(ph[h[c]], ph[h[f]]);
      f = c, c <<= 1;
    }
    else return;
  }
}

void push(int dp[nMax], int x) {
  //printf("push(%d)\n", x);
  h[++k] = x, ph[x] = k;
  combTop(dp, k);
}

int pop(int dp[nMax]) {
  int x = h[1];
  //printf("pop(%d)\n", x);
  h[1] = h[k--];
  if(k) ph[h[1]] = 1, combDown(dp, 1);
  return x;
}

void solve()
{
    for (int i = 0; i <= K; ++i) dijkstra(dp[i],c[i]);
    p2[1] = 1;
    for (int i = 2; i < 17; ++i) p2[i] = p2[i-1] << 1;
}

void dijkstra(int dp[nMax], int x) {

  //printf("dijkstra(%d)\n", x);

  for(int i = 1; i <= n; ++i)
    dp[i] = inf, ph[i] = 0;

  dp[x] = 0; push(dp, x);
  while(k) {
    x = pop(dp);
    //printf("%d %d\n", k, x);
    /// asa e mai rapid
    unsigned end = v[x].size();
    for(unsigned i = 0; i < end; ++i)
      if(dp[x] + v[x][i].second < dp[v[x][i].first]) {
        dp[v[x][i].first] = dp[x] + v[x][i].second;
        if(ph[v[x][i].first]) combTop(dp, ph[v[x][i].first]);
        else push(dp, v[x][i].first);
      }
  }
}

void ReadData()
{
    scanf("%d%d", &n, &m);
    scanf("%d", &K);
    int i, x, y, z;
    c[0] = 1;
    for (i = 1; i <= K; ++i)
    {
        scanf("%d", &c[i]);
        poz[c[i]] = i;
    }
    for (i = 0; i < m; ++i)
    {
        scanf("%d%d%d", &x, &y, &z);
        v[x].push_back(make_pair(y,z));
        v[y].push_back(make_pair(x,z));
    }

    memset(cost, inf, sizeof(cost));
}
*/
/*
/// Punncte = 50, TIME = tle
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>

#define nMax 2002

using namespace std;

const int inf = 0x3f3f3f3f;

int dp[16][nMax];
int ph[nMax], h[nMax];
int poz[nMax], uz[nMax], p[16];
vector < pair< int,int > > v[nMax];
int c[16], cost[16][1<<17];
int k, n, m, K;
int optim = inf, best;

void ReadData();
void PrintSol();
void solve();
void combTop(int dp[nMax], int c);
void combDown(int dp[nMax], int f);
void push(int dp[nMax], int x);
int pop(int dp[nMax]);
void dijkstra(int dp[nMax], int x);
void GenPerm(int t);

int main()
{
    freopen("14-ubuntzei.in", "rt", stdin);
    //freopen("ubuntzei.out", "wt", stdout);

    ReadData();
    solve();
    GenPerm( 1 );
    PrintSol();

    fclose(stdin);
    fclose(stdout);
    return 0;
}

void PrintSol()
{
    printf("%d\n", optim);
}

void GenPerm(int t)
{
    if (t > K)
    {
        if (best+dp[poz[p[K]]][n] < optim) optim = best+dp[poz[p[K]]][n];
    }
    else
    for (int i = 1; i <= K; ++i)
       if (!uz[c[i]] and best+dp[poz[p[t-1]]][c[i]] < optim)
       {
           uz[c[i]] = 1;
           p[t] = c[i];
           best += dp[poz[p[t-1]]][c[i]];
           ///printf("%d\n", best);
           GenPerm(t+1);
           uz[c[i]] = 0;
           best -= dp[poz[p[t-1]]][c[i]];
       }
}

void combTop(int dp[nMax], int c) {
  int f = c>>1;
  while(f && dp[h[f]] > dp[h[c]]) {
    swap(h[f], h[c]);
    swap(ph[h[f]], ph[h[c]]);
    c = f, f >>= 1;
  }
}

void combDown(int dp[nMax], int f) {
  int c = f<<1;
  while(c <= k) {
    if(c < k && dp[h[c+1]] < dp[h[c]]) ++c;
    if(dp[h[c]] < dp[h[f]]) {
      swap(h[c], h[f]);
      swap(ph[h[c]], ph[h[f]]);
      f = c, c <<= 1;
    }
    else return;
  }
}

void push(int dp[nMax], int x) {
  //printf("push(%d)\n", x);
  h[++k] = x, ph[x] = k;
  combTop(dp, k);
}

int pop(int dp[nMax]) {
  int x = h[1];
  //printf("pop(%d)\n", x);
  h[1] = h[k--];
  if(k) ph[h[1]] = 1, combDown(dp, 1);
  return x;
}

void solve()
{
    int i;
    for (i = 0; i <= K; ++i)
    {
        dijkstra(dp[i],c[i]);
    }
}

void dijkstra(int dp[nMax], int x) {

  //printf("dijkstra(%d)\n", x);

  for(int i = 1; i <= n; ++i)
    dp[i] = inf, ph[i] = 0;

  dp[x] = 0; push(dp, x);
  while(k) {
    x = pop(dp);
    //printf("%d %d\n", k, x);
    /// asa e mai rapid
    unsigned end = v[x].size();
    for(unsigned i = 0; i < end; ++i)
      if(dp[x] + v[x][i].second < dp[v[x][i].first]) {
        dp[v[x][i].first] = dp[x] + v[x][i].second;
        if(ph[v[x][i].first]) combTop(dp, ph[v[x][i].first]);
        else push(dp, v[x][i].first);
      }
  }
}

void ReadData()
{
    scanf("%d%d", &n, &m);
    scanf("%d", &K);
    int i, x, y, z;
    c[0] = 1;
    for (i = 1; i <= K; ++i)
    {
        scanf("%d", &c[i]);
        poz[c[i]] = i;
    }
    for (i = 0; i < m; ++i)
    {
        scanf("%d%d%d", &x, &y, &z);
        v[x].push_back(make_pair(y,z));
        v[y].push_back(make_pair(x,z));
    }
}
*/