Cod sursa(job #2624527)

Utilizator loraclorac lorac lorac Data 4 iunie 2020 22:35:52
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.24 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream cin("cuplaj.in");
ofstream cout("cuplaj.out");
const int lim=2e5+3;
struct Op
{
    int nod;int capp;int opus;
};
vector<Op> vec[lim];
pair<int,int> pred[lim];
queue<int> q;
int main()
{
    int n,m,e,x,y;
    cin>>n>>m>>e;
    for(int i=1;i<=e;++i)
    {
        cin>>x>>y;
        int nr1=vec[x].size();
        int nr2=vec[y+n].size();
        vec[x].push_back({y+n,1,nr2});
        vec[y+n].push_back({x,0,nr1});
    }
    for(int i=1;i<=n;++i)
    {
        int nr1=vec[0].size();
        int nr2=vec[i].size();
        vec[0].push_back({i,1,nr2});
        vec[i].push_back({0,0,nr1});
    }
    for(int i=n+1;i<=n+m;++i)
    {
        int nr1=vec[i].size();
        int nr2=vec[n+m+1].size();
        vec[i].push_back({n+m+1,1,nr2});
        vec[n+m+1].push_back({i,0,nr1});
    }
    int flow=0,ads;
    do
    {
        for(int i=1;i<=n+m+1;++i)
            pred[i]={0,0};
        pred[0]={-1,-1};
        q.push(0);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=0;i<vec[x].size();++i)
            if(pred[vec[x][i].nod].first==0 and vec[x][i].capp>0)
            {
                pred[vec[x][i].nod]={x,i};
                q.push(vec[x][i].nod);
            }
        }
        if(pred[n+m+1].first)
        for(int i=n+1;i<=n+m;++i)
        if(pred[i].first)
        {
            int nr=vec[i].size()-1;
            ads=vec[i][nr].capp;
            for(int k=i;pred[k].first>=0;k=pred[k].first)
                ads=min(ads,vec[pred[k].first][pred[k].second].capp);
            if(ads<=0) continue;
            vec[i][nr].capp-=ads;
            vec[n+m+1][vec[i][nr].opus].capp+=ads;
            for(int k=i;pred[k].first>=0;k=pred[k].first)
            {
                vec[pred[k].first][pred[k].second].capp-=ads;
                vec[vec[pred[k].first][pred[k].second].nod][vec[pred[k].first][pred[k].second].opus].capp+=ads;
            }
            flow+=ads;
        }
    }while(pred[n+m+1].first);
    cout<<flow<<'\n';
    for(int i=1;i<=n;++i)
    for(auto t:vec[i])
    if(t.capp==0 and t.nod>n) cout<<i<<' '<<t.nod-n<<'\n';
    return 0;
}