Cod sursa(job #1402062)

Utilizator mihail.jianuJianu Mihail mihail.jianu Data 26 martie 2015 11:59:02
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.32 kb
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int N=700;
const int M=50000;
const int INF=20000;
class To{
    public:
        int v,c;
        To(){
        }
        To(int vv,int cc){
            v=vv;
            c=cc;
        }
};
queue<int>q;
vector<To>g[N+1];
int can[N+1][N+1];
bool ok[N+1][N+1];
int pos[N+1][N+1];
int dist[N+1];
bool vis[N+1];
int father[N+1];
bool queued[N+1];
int n1,n2,m,n;
int flow,cost;
void bellman_ford(){
    memset(vis,0,sizeof(vis));
    memset(queued,0,sizeof(queued));
    memset(father,0,sizeof(father));
    vis[0]=true;
    q.push(0);
    queued[0]=true;
    for(int i=1;i<=n;i++)
        dist[i]=INF*M+1;
    while(!q.empty()){
        int dad=q.front();
        q.pop();
        for(unsigned int i=0;i<g[dad].size();i++){
            To son=g[dad][i];
            if(dist[son.v]>dist[dad]+son.c&&can[dad][son.v]){
                dist[son.v]=dist[dad]+son.c;
                vis[son.v]=true;
                if(!queued[son.v])
                    q.push(son.v);
                queued[son.v]=true;
                father[son.v]=dad;
            }
        }
        queued[dad]=false;
    }
}
void update(){
    int node=n;
    while(node){
        can[father[node]][node]--;
        can[node][father[node]]++;
        node=father[node];
    }
}
int main(){
    freopen("cmcm.in","r",stdin);
    freopen("cmcm.out","w",stdout);
    scanf("%d%d%d",&n1,&n2,&m);
    n=n1+n2+1;
    for(int i=1;i<=m;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        y+=n1;
        g[x].push_back(To(y,z));
        g[y].push_back(To(x,-z));
        can[x][y]=1;
        pos[x][y]=i;
        ok[x][y]=true;
    }
    for(int i=1;i<=n1;i++){
        g[0].push_back(To(i,0));
        g[i].push_back(To(0,0));
        can[0][i]=1;
    }
    for(int i=n1+1;i<n;i++){
        g[n].push_back(To(i,0));
        g[i].push_back(To(n,0));
        can[i][n]=1;
    }
    while(true){
        bellman_ford();
        if(!vis[n])
            break;
        update();
        flow++;
        cost+=dist[n];
    }
    printf("%d %d\n",flow,cost);
    for(int i=1;i<=n1;i++)
        for(int j=n1+1;j<=n1+n2;j++)
            if(ok[i][j]&&!can[i][j])
                printf("%d ",pos[i][j]);
    return 0;
}