Cod sursa(job #464592)

Utilizator mgntMarius B mgnt Data 20 iunie 2010 23:17:23
Problema Critice Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.17 kb
#include <fstream>
#include <iostream>
#include <cassert>
using namespace std;

// Dinic
int const maxn = 1000;
typedef int A1[maxn]; typedef int A2[maxn][maxn]; A1 cnt, lev, inv, que; A2 out;
int dinic(int n, A1 deg, A2 adj, A2 cap, int s, int t)
{
  int flow = 0, i=-1, qo=-1, qi=-1, v=-1, w=-1, act=-1, dt=-1, dt1=-1, oldd=-1;
  while (true)
  { for (i=0; n>i; ++i) { lev[i]=-1; cnt[i]=0; }
    lev[s]=0; que[0]=s; qo=0; qi=1;
    while ((qo<qi) && ((-1==lev[t])||((1+lev[que[qo]])==lev[t])))
    { v = que[qo]; ++ qo;
      for (i=0; i<deg[v]; ++i)
      { w = adj[v][i];
        if (0<cap[v][w])
        { if (-1==lev[w]) { lev[w]=1+lev[v]; que[qi]=w; ++qi; }
          if ((1+lev[v])==lev[w]) { out[v][cnt[v]]=w; ++cnt[v]; }
        }
      }
    }
    if (-1 == lev[t]) { return flow; }
    assert(oldd<lev[t]); oldd=lev[t];
    act = 4; dt=0;
    while (0 != act)
    {
      while((1==act) || (2==act))
      {
        while(1==act)
        { /* advance */
          w = (0<cnt[v])?out[v][0]:-1;
          while((-1!=w) && ((n<lev[w])||(0==cap[v][w])))
          { out[v][0]=out[v][cnt[v]-1]; --cnt[v];
            w=(0<cnt[v])?out[v][0]:-1;
          }
          assert(((-1==w)||(0<cap[v][w])));
          if (-1 != w)
          { inv[w]=v; v=w;
            if (t==v) { act = 3; /* goto augument */ }
          }
          else { act = 2; /* goto retreat */ }
        }
        if(2==act)
        { /* retreat */
          if (s==v)  { act=0; /* stop */ }
          else
          { lev[v]=1+n; v=inv[v]; act = 1; /* goto advance */ }
        }
      }
      if(3==act)
      { /* augument */
        dt = cap[inv[t]][t];
        for (i=t;i!=s;i=inv[i]) { dt1 = cap[inv[i]][i]; if (dt>dt1) { dt = dt1; } }
        assert(0<dt);
        for (i=t;i!=s;i=inv[i]) { cap[inv[i]][i] -= dt; cap[i][inv[i]] += dt; }
        flow += dt; act = 4; /* goto init */
      }
      if(4==act) { /* init */ v=s; act=1; /* goto advance */ }
    }
    assert(0<dt);
  }
  return -1;
}

A1 deg, Q, F; A2 adj, cap; int const maxm = 10000; int X[maxm], Y[maxm];
A2 sel;

int main()
{
  ifstream is("critice.in");
  ofstream os("critice.out");
  int n, m, i,u,w,c,qi,qo, k;
  is >> n >> m;
  for (i=0; n>i; ++i) { deg[i]=0; }
  for (i=0; m>i; ++i)
  { is>>u>>w>>c; --u; --w; X[i]=u; Y[i]=w; cap[u][w]=cap[w][u]=c;
    adj[u][deg[u]]=w; adj[w][deg[w]]=u; ++deg[u]; ++deg[w];
  }
  (void) dinic(n, deg, adj, cap, 0, n-1);
  for (u=0; n>u; ++u)
  { for (i=0; deg[u]>i; ++i)
    { w = adj[u][i]; sel[u][w]=0; }
  }
  for (i=0; n>i; ++i) { F[i]=1; }
  F[0]=0; Q[0]=0; qo=0; qi=1;
  while (qo<qi)
  { u=Q[qo]; ++qo;
    for (i=0; deg[u]>i; ++i)
    { w=adj[u][i];
      if (0<cap[u][w]) { if (F[w]) { F[w]=0; Q[qi]=w; ++qi; } }
      else { sel[u][w]=sel[u][w] | 1; sel[w][u]=sel[w][u] | 1; }
    }
  }
  for (i=0; n>i; ++i) { F[i]=1; }
  F[n-1]=0; Q[0]=n-1; qo=0; qi=1;
  while (qo<qi)
  { u=Q[qo]; ++qo;
    for (i=0; deg[u]>i; ++i)
    { w=adj[u][i];
      if (0<cap[w][u]) { if (F[w]) { F[w]=0; Q[qi]=w; ++qi; } }
      else { sel[w][u]=sel[w][u] | 2; sel[u][w]=sel[u][w] | 2; }
    }
  }
  for (i=0; m>i; ++i) { if (3==sel[X[i]][Y[i]]) { ++k; } }
  os << k << endl;
  for (i=0; m>i; ++i) { if (3==sel[X[i]][Y[i]]) { os << 1+i << endl; } }
  return 0;
}