Cod sursa(job #1826004)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 9 decembrie 2016 22:34:57
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.37 kb
#include <cstdio>
#include <vector>
#define MAXN 301
#define INF 1000000000
#define MAXQ (1<<18)
std::vector <int> G[MAXN*2+1];
inline void add_Edge(int a,int b){
    G[a].push_back(b);
}
int cap[2*MAXN+1][2*MAXN+1];
int flux[2*MAXN+1][2*MAXN+1];
int cost[2*MAXN+1][2*MAXN+1];
int poz[2*MAXN+1][2*MAXN+1];
int dist[2*MAXN+1];
int from[2*MAXN+1];
int Q[MAXQ];
bool inQ[2*MAXN+1];
int C;
inline int BF(int S,int D,int n){
    int i,b,e,nod,x;
    for(i=1;i<=n;i++)
      dist[i]=INF;
    dist[S]=0;
    b=0;
    e=1;
    Q[0]=S;
    inQ[S]=1;
    while(b!=e){
       nod=Q[b];
       inQ[nod]=0;
       for(i=0;i<G[nod].size();i++){
        x=G[nod][i];
        if(cap[nod][x]>flux[nod][x]&&dist[x]>dist[nod]+cost[nod][x]){
           dist[x]=dist[nod]+cost[nod][x];
           from[x]=nod;
           if(inQ[x]==0&&x!=D){
              inQ[x]=1;
              Q[e]=x;
              e++;
              e&=(MAXQ-1);
           }
        }
       }
        b++;
        b&=(MAXQ-1);
    }
    C=dist[D];
    return dist[D];
}
int main(){
    FILE*fi,*fout;
    int i,j,n,m,e,x,y,c,S,D,Flow,Cost,nod,min;
    fi=fopen("cmcm.in" ,"r");
    fout=fopen("cmcm.out" ,"w");
    fscanf(fi,"%d %d %d " ,&n,&m,&e);
    for(i=1;i<=e;i++){
       fscanf(fi,"%d %d %d " ,&x,&y,&c);
       y+=n;
       add_Edge(x,y);
       add_Edge(y,x);
       cap[x][y]=1;
       cost[x][y]=c;
       cost[y][x]=-c;
       poz[x][y]=poz[y][x]=i;
    }
    S=n+m+1;
    D=n+m+2;
    for(i=1;i<=n;i++){
       add_Edge(S,i);
       add_Edge(i,S);
       cap[S][i]=1;
    }
    for(i=1;i<=m;i++){
       add_Edge(i+n,D);
       add_Edge(D,i+n);
       cap[i+n][D]=1;
    }
    Flow=0;
    Cost=0;
    while(BF(S,D,n+m+2)<INF){
       nod=D;
       min=INF;
       while(from[nod]>0){
          if(min>cap[from[nod]][nod]-flux[from[nod]][nod])
             min=cap[from[nod]][nod]-flux[from[nod]][nod];
          nod=from[nod];
       }
       nod=D;
       while(from[nod]>0){
          flux[from[nod]][nod]+=min;
          flux[nod][from[nod]]-=min;
          nod=from[nod];
       }
       Flow+=min;
       Cost+=C*min;
    }
    fprintf(fout,"%d %d\n" ,Flow,Cost);
    for(i=1;i<=n;i++)
     for(j=n+1;j<=n+m;j++)
      if(flux[i][j]==cap[i][j]&&cap[i][j]==1)
        fprintf(fout,"%d " ,poz[i][j]);
    fclose(fi);
    fclose(fout);
    return 0;
}