Cod sursa(job #2945481)

Utilizator NutaAlexandruASN49K NutaAlexandru Data 23 noiembrie 2022 20:11:04
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.91 kb
#include <fstream>
#include<vector>
#include <algorithm>
#import <cmath>
#import <cassert>
#import <queue>
using namespace std;
class flux
{
    struct duo
    {
        int nod,val;
        bool operator ()(duo a,duo b)
        {
            return (a.val>b.val);
        }
    };
    vector<vector<int>>f,cap;
    vector<int>t;
    vector<vector<duo>>a;
    int n;
    vector<int>dist;
    void ford(int s)
    {
        fill(dist.begin(),dist.end(),2e9);
        dist[s]=0;
        queue<duo>q;
        q.push({s,0});
        while(q.size())
        {
            auto acm=q.front();
            q.pop();
            if(acm.val!=dist[acm.nod])continue;
            for(auto &c:a[acm.nod])
            {
                if(cap[acm.nod][c.nod]!=f[acm.nod][c.nod] && dist[acm.nod]+c.val<dist[c.nod])
                {
                    dist[c.nod]=dist[acm.nod]+c.val;
                    q.push({c.nod,dist[c.nod]});
                }
            }
        }
    }
    vector<int>real,lie;
    bool dij(int s,int d)
    {
        fill(real.begin(),real.end(),2e9);
        fill(lie.begin(),lie.end(),2e9);
        priority_queue<duo,vector<duo>,duo>q;
        q.push({s,0});
        real[s]=lie[s]=0;
        while(q.size())
        {
            auto acm=q.top();
            q.pop();
            if(acm.val!=lie[acm.nod])continue;
            for(auto &c:a[acm.nod])
            {
                if(f[acm.nod][c.nod]!=cap[acm.nod][c.nod] && acm.val+c.val+dist[acm.nod]-dist[c.nod]<lie[c.nod])
                {
                    lie[c.nod]=acm.val+c.val+dist[acm.nod]-dist[c.nod];
                    real[c.nod]=real[acm.nod]+c.val;
                    t[c.nod]=acm.nod;
                    q.push({c.nod,lie[c.nod]});
                }
            }

        }
        return (real[d]!=2e9);
    }
    bool ford(int s,int d)
    {
        fill(dist.begin(),dist.end(),2e9);
        dist[s]=0;
        queue<duo>q;
        q.push({s,0});
        while(q.size())
        {
            auto acm=q.front();
            q.pop();
            if(acm.val!=dist[acm.nod])continue;
            for(auto &c:a[acm.nod])
            {
                if(cap[acm.nod][c.nod]!=f[acm.nod][c.nod] && dist[acm.nod]+c.val<dist[c.nod])
                {
                    t[c.nod]=acm.nod;
                    dist[c.nod]=dist[acm.nod]+c.val;
                    if(c.nod!=d)
                    {
                        q.push({c.nod,dist[c.nod]});
                    }
                }
            }
        }
        return (dist[d]!=2e9);
    }
public:
    flux(int n)
    {
        this->n=n;
        a=vector<vector<duo>>(n+1);
        f=cap=vector<vector<int>>(n+1,vector<int>(n+1,0));
        t=dist=real=lie=vector<int>(n+1);
    }
    void add_edge(int x,int y,int cap,int cost)
    {
        this->cap[x][y]=cap;
        a[x].push_back({y,cost});
        a[y].push_back({x,-cost});
    }
    void init(int s)
    {
        ford(s);
    }
    int get_ans(int s,int d)
    {
        int rez=0;
        init(s);
        while(dij(s,d))
        {
            int val=2e9;
            for(int i=d;i!=s;i=t[i])
            {
                val=min(val,cap[t[i]][i]-f[t[i]][i]);
            }
            for(int i=d;i!=s;i=t[i])
            {
                f[t[i]][i]+=val;
                f[i][t[i]]-=val;
            }
            rez+=(val*real[d]);
        }
        return rez;
    }
};


main()
{
    ifstream cin("cc.in");
    ofstream cout("cc.out");
    int n,m,q;
    cin>>n;
    const int s=0,d=2*n+1;
    flux solve(d+1);
    for(int i=1;i<=n;i++)
    {
        solve.add_edge(s,i,1,0);
        solve.add_edge(i+n,d,1,0);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=n+1;j<=2*n;j++)
        {
            int x;
            cin>>x;
            solve.add_edge(i,j,1,x);
        }
    }
    cout<<solve.get_ans(s,d);

}