Cod sursa(job #1390547)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 17 martie 2015 09:27:11
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.45 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;
vector <int> G[605];
int N,M,E;
queue <int> Q;
const int INF = 1000000000;
int Edge[305][305],Cost[305][305],Father[605],Capacity[305][305],F[305][305],Distance[605],InQ[605];
int source,sink;
void Read()
{
    scanf("%d%d%d",&N,&M,&E);
    for(int i=1;i<=E;i++)
    {
        int x,y,c;
        scanf("%d%d%d",&x,&y,&c);
        y+=N;
        G[x].push_back(y);
        G[y].push_back(x);
        Edge[x][y]=i;
        Cost[x][y]=c;
        Cost[y][x]=-c;
        Capacity[x][y]=1;
    }
    sink=N+M+1;
    for(int i=1;i<=N;i++)
    {
        G[source].push_back(i);
        G[i].push_back(source);
        Capacity[source][i]=1;
    }
    for(int i=N+1;i<=M+N;i++)
    {
        G[sink].push_back(i);
        G[i].push_back(sink);
        Capacity[i][sink]=1;
    }
}
void init()
{
    memset(Father,-1,sizeof(Father));
    for(int i=1;i<=N+M+1;i++)
        Distance[i]=INF;
    memset(InQ,0,sizeof(InQ));
    Q.push(source);
    InQ[source]=1;
    Distance[source]=0;
}
bool bellmanFord()
{
    init();
    while(!Q.empty())
    {
        int x=Q.front();
        InQ[x]=0;
        Q.pop();
        for(int i=0;i<G[x].size();i++)
        {
            int neighb=G[x][i];
            if(Capacity[x][neighb]-F[x][neighb]>0 && Distance[x]+Cost[x][neighb]<Distance[neighb])
            {
                Distance[neighb]=Distance[x]+Cost[x][neighb];
                Father[neighb]=x;
                if(InQ[neighb]==0)
                {
                    Q.push(neighb);
                    InQ[neighb]=1;
                }
            }
        }
    }
    return Father[sink]!=-1;
}
void MaxFlow()
{
    int MaxFlow=0,Min=0;
    while(bellmanFord()==1)
    {
        int flow=N;
        for(int node=sink;node!=source;node=Father[node])
            flow=min(flow,Capacity[Father[node]][node]-F[Father[node]][node]);
        for(int node=sink;node!=source;node=Father[node])
            F[Father[node]][node]+=flow,F[node][Father[node]]-=flow;
        MaxFlow+=flow;Min+=Distance[sink]*flow;
    }
    printf("%d %d\n",MaxFlow,Min);
}
int main()
{
    freopen("cmcm.in","r",stdin);
    freopen("cmcm.out","w",stdout);
    Read();
    MaxFlow();
    for(int i=1;i<=N;i++)
        for(int j=N+1;j<=M+N;j++)
            if(F[i][j]>0)
                printf("%d ",Edge[i][j]);
    return 0;
}