Cod sursa(job #1409448)

Utilizator eustatiuDima Eustatiu eustatiu Data 30 martie 2015 15:34:16
Problema Critice Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.63 kb
#include <stdio.h>
#include <vector>
#include <string.h>
#include <algorithm>
#include <cassert>
#include <ctime>
#include <cstdlib>
#include<iostream>
using namespace std;

#define pb push_back
#define FORIT( it, v ) for( typeof((v).begin()) it=(v).begin(); it!=(v).end(); ++it )
#define MaxN 1010
#define MaxM 10010

int i,n,m,x,y,z,maxflow,Number;
int Father[MaxN];
vector <int> Vertex[MaxN];

struct edge
{
    int a,b,c,f;
    bool marked;
    edge ()
    {
        a=b=c=f=0;
        marked=false;
    }
    edge (int x,int y,int z)
    {
        a=x;
        b=y;
        c=z;
        f=0;
        marked=false;
    }
    int length (int x)
    {
        if (x==b)
            return c-f;
        return c+f;
    }
    void increase (int x, int value )
    {
        if (x==b)
            f+=value;
        else
            f-=value;
    }
    int other (int node)
    {
        return a+b-node;
    }
    void print()
    {
        printf ("%ld %ld %ld %ld %d\n",a,b,c,f,marked);
    }
}Edge[MaxM];
int Queue[MaxN];
int BFS()
{
    int node,left,right,next,last,value;
    edge ed1,ed2;
    left=1;
    right=1;
    Queue[1]=1;
    //Put first node into queue;
    while ( left <= right )
    {
        node=Queue[left++];
        if (node==n)
            continue;
        for( vector <int>::iterator it=(Vertex[node]).begin(); it!=(Vertex[node]).end(); ++it )
        //FORIT (it,Vertex[node])
        {
            ed1=Edge[*it];
            next=ed1.other(node);
            //pull the other node from curentWe found a path from source to sink edge
            if (!Father[next] && ed1.length(next)>0 )
            {
                Father[next]=*it;
                Queue[++right]=next;
            }
        };
    }
    bool ok=0;
    for( vector <int>::iterator it=(Vertex[n]).begin(); it!=(Vertex[n]).end(); ++it )
    {
        ed1=Edge[*it];
        last=ed1.other(n);
        //pull the other node from curent edge
        if (Father[last])
        {
            // We found a path from source to sink
            value=ed1.length(n);
            if ( value > 0 )
            {
                //We go back to the source
                node = last;
                while ( node!=1)
                {
                    ed1 = Edge[Father[node]];
                    last = ed1.other(node);
                    value = min (value , ed1.length(node));
                    node = last;
                }
                node = Edge[*it].other(n);
                if (value > 0)
                {
                    ok=1;
                    Edge[*it].increase(n,value);
                    while (node !=1)
                    {
                        last=Edge[Father[node]].other(node);
                        Edge[Father[node]].increase(node,value);
                        node = last;
                    }
                    maxflow+=value;
                }

            }
        }
    };
    return ok;
}
int ok,solution,visited[3][MaxN];
void solve(int x,int color)
{
    int node,left,right,next,last,value;
    edge ed;
    left=1;
    right=1;
    Queue[1]=x;
    visited[color][x]=1;
    while (left<=right)
    {
        node=Queue[left++];
        for( vector <int>::iterator it=(Vertex[node]).begin(); it!=(Vertex[node]).end(); ++it )
        {
            ed=Edge[*it];
            next=ed.other(node);
            value=ed.length(next);
            if (!visited[color][next]&&value)
            {
                visited[color][next]=1;
                Queue[++right]=next;
            }
        }
    }
}
int main()
{
    freopen ("critice.in","r",stdin);
    freopen ("critice.out","w",stdout);
    scanf ("%d%d",&n,&m);
    for (i=1;i<=m;i++)
    {
        scanf ("%d%d%d",&x,&y,&z);
        Edge[i] = edge(x,y,z);
        Vertex[x].pb(i);
        Vertex[y].pb(i);
    }
    Father[1]=1;
    while ( BFS() )
        memset(Father,0,sizeof Father),Father[1]=1;
    solve(1,1);
    solve(n,2);
    Number=0;
    edge ed;
    int next;
    for (i=1;i<=n;i++)
    {
        for( vector <int>::iterator it=(Vertex[i]).begin(); it!=(Vertex[i]).end(); ++it )
        {
            ed=Edge[*it];
            next=ed.other(i);
            if (visited[1][i]&&visited[2][next]&&!ed.length(next))
            {
                if (ed.marked==0)
                {
                    Number++;
                    Edge[*it].marked=true;
                }
            }
        }
    }
    printf ("%d\n",Number);
    for (i=1;i<=m;i++)
        if (Edge[i].marked)
            printf ("%d\n",i);

    return 0;
}