Cod sursa(job #610035)

Utilizator 0pt1musOptimus 0pt1mus Data 24 august 2011 15:00:23
Problema Critice Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.13 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>

#define grafSize 1001
#define edgeSize 10001
#define useSize 1001
#define TSize 1001
#define cHeight 1001
#define cWidth 1001
#define fHeight 1001
#define fWidth 1001
#define vSize 10001
#define T1Size 1001
#define T2Size 1001

#define A (*it)

#define OPT 0x7fffffff

#define ONE int

using namespace std;

ifstream in;
ofstream out;

vector <ONE> graf[grafSize];

int c[cHeight][cWidth];
int f[fHeight][fWidth];

int ex[edgeSize];
int ey[edgeSize];
int T[TSize];
int T1[T1Size];
int T2[T2Size];
int v[vSize];

int M,N,sol=0;
int Source,Sink;

inline void read(void)
{
    int x,y;

    in.open("critice.in");

    in>>N>>M;
    for(int i=1;i<=M;++i)
    {
        in>>x>>y;
        in>>c[x][y];
        c[y][x]=c[x][y];

        ex[i]=x;
        ey[i]=y;

        graf[x].push_back(y);
        graf[y].push_back(x);
    }

    in.close();

    Source=1;
    Sink=N;
}

inline void write(void)
{
    out.open("critice.out");

    out<<sol<<'\n';

    for(int i=1;i<=sol;++i)
        out<<v[i]<<'\n';

    out.close();
}

inline int flowBFS(void)
{
    queue <ONE> q;
    int use[useSize];
    int ok=0;

    memset(use,0,sizeof(use));
    memset(T,0,sizeof(T));

    q.push(Source);
    use[Source]=1;

    for(int nod;!q.empty();q.pop())
    {
        nod=q.front();

        for(vector <ONE>::iterator it=graf[nod].begin();it!=graf[nod].end();++it)
            if(!use[A]&&c[nod][A]>f[nod][A])
            {
                if(A!=Sink)
                {
                    use[A]=1;
                    T[A]=nod;
                    q.push(A);
                }
                else ok=1;
            }
    }

    return ok;
}

inline void edgeBFS1(void)
{
    queue <ONE> q;
    int use[useSize];
    int nod;

    memset(T1,0,sizeof(T1));
    memset(use,0,sizeof(use));

    q.push(Source);
    use[Source]=1;

    for(;!q.empty();q.pop())
    {
        nod=q.front();

        for(vector <ONE>::iterator it=graf[nod].begin();it!=graf[nod].end();++it)
            if(c[nod][A]>f[nod][A]&&!use[A])
            {
                T1[A]=nod;
                use[A]=1;
                q.push(A);
            }
    }
}

inline void edgeBFS2(void)
{
    queue <ONE> q;
    int use[useSize];
    int nod;

    memset(T2,0,sizeof(T2));
    memset(use,0,sizeof(use));

    q.push(Sink);
    use[Sink]=1;

    for(;!q.empty();q.pop())
    {
        nod=q.front();

        for(vector <ONE>::iterator it=graf[nod].begin();it!=graf[nod].end();++it)
            if(c[A][nod]>f[A][nod]&&!use[A])
            {
                T2[A]=nod;
                use[A]=1;
                q.push(A);
            }
    }
}

inline int ABS(int x)
{
    if(x<0) return -x;
    else return x;
}

inline void maxflow(void)
{
    for(int nod,min,drum=flowBFS();drum;drum=flowBFS())
        for(vector <ONE>::iterator it=graf[Sink].begin();it!=graf[Sink].end();++it)
            if(T[A]!=0)
            {
                T[Sink]=A;

                min=OPT;

                nod=Sink;
                while(nod!=Source)
                {
                    if(min>c[T[nod]][nod]-f[T[nod]][nod])
                        min=c[T[nod]][nod]-f[T[nod]][nod];
                    nod=T[nod];
                }

                if(min<=0) continue;

                nod=Sink;
                while(nod!=Source)
                {
                    f[T[nod]][nod]+=min;
                    f[nod][T[nod]]-=min;
                    nod=T[nod];
                }
            }
}

inline void critice(void)
{
    memset(T1,0,sizeof(T1));
    memset(T2,0,sizeof(T2));

    edgeBFS1();
    edgeBFS2();

    T1[Source]=Source;
    T2[Sink]=Sink;

    for(int i=1;i<=M;++i)
        if(c[ex[i]][ey[i]]==ABS(f[ex[i]][ey[i]]))
        {
            if(T1[ex[i]]!=0&&T2[ey[i]]!=0) v[++sol]=i;
            else
            if(T1[ey[i]]!=0&&T2[ex[i]]!=0) v[++sol]=i;
        }
}

int main(void)
{
    read();
    maxflow();
    critice();
    write();

    return 0;
}