Cod sursa(job #697064)

Utilizator giuliastefGiulia Stef giuliastef Data 28 februarie 2012 21:55:12
Problema Cuplaj maxim de cost minim Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.11 kb
#include <fstream>
#include <vector>
#define NMAX 711
#define INF 1<<28
using namespace std;
vector <int> G[NMAX];
int N,M,S,D,Sol;
int edge[NMAX][NMAX],cost[NMAX][NMAX],f[NMAX][NMAX],dist[NMAX],t[NMAX],q[NMAX],use[NMAX];
void Read(){
     int E,p,q,val,i;
     ifstream in("cmcm.in");
     in>>N>>M>>E;
     for(i=1;i<=E;i++){
      in>>p>>q>>val;
      p++; q+=N+1;
      G[p].push_back(q); cost[p][q]=val;
      G[q].push_back(p); cost[q][p]=-val;
      edge[p][q]=i;
      f[p][q]=1;
     }
     in.close();
}
void Build_Graph(){
     int i;
     S=1, D=N+M+2;
     for(i=2;i<=N+1;i++) {
      G[S].push_back(i);
      G[i].push_back(S);
      f[S][i]=1;
     }
     for(i=N+2;i<=N+M+1;i++){
      G[i].push_back(D);
      G[D].push_back(i);
      f[i][D]=1;
     }
}
bool BellmanFord(){
     int i,st,dr,nod;
     for(i=S;i<=D;i++){
      dist[i]=INF;
      use[i]=0;
      t[i]=0;
     }
     st=0, dr=1, dist[S]=0, q[1]=S;
     while(st<dr){
      st++;
      nod=q[st];
      for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();it++)
       if(f[nod][*it]>0 && dist[*it]> dist[nod]+ cost[nod][*it]){
        dist[*it]=dist[nod]+cost[nod][*it];
        t[*it]=nod;
        if(!use[*it]){
         q[++dr]=*it;
         use[*it]=1;
        }
       }
       use[nod]=0;
     }
     if(dist[D]==INF) return 0;
     return 1;
}
void Solve(){
     int i,flux;
     Build_Graph();
     while(BellmanFord()){
      flux=INF;
      for(i=D;i!=S;i=t[i])
       flux=min(flux,f[t[i]][i]);
      for(i=D;i!=S;i=t[i]){
       f[t[i]][i]-=flux;
       f[i][t[i]]+=flux;
      }
      Sol+=flux*dist[D];
     }
}
void Write(){
     int i,j,Nr=0;
     ofstream out("cmcm.out");
     for(i=2;i<=N+1;i++)
      for(j=N+2;j<D;j++)
       if(!f[i][j]){
        Nr++;
        break;
       }
     out<<Nr<<" "<<Sol<<'\n';
     for(i=2;i<=N+1;i++)
      for(j=N+2;j<D;j++)
       if(!f[i][j] && edge[i][j]){
        out<<edge[i][j]<<" ";
        break;
       }
     out<<'\n';
     out.close();
}
int main(){
    Read();
    Solve();
    Write();
    return 0;
}