Cod sursa(job #2958570)

Utilizator Tudose_StefanTudose Alexandru Stefan Tudose_Stefan Data 26 decembrie 2022 23:15:54
Problema Cuplaj maxim in graf bipartit Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.25 kb
#include <bits/stdc++.h>

using namespace std;

///parsez intrare si citire (functii luate de pe net care, recunosc, nu stiu ce fac)
class InParser {
    vector<char> str;
    int ptr;
    ifstream fin;

    char getChar() {
        if (ptr == int(str.size())) {
            fin.read(str.data(), str.size());
            ptr = 0;
        }
        return str[ptr++];
    }

    template<class T>
    T getInt() {
        char chr = getChar();
        while (!isdigit(chr) && chr != '-')
            chr = getChar();
        int sgn = +1;
        if (chr == '-') {
            sgn = -1;
            chr = getChar();
        }
        T num = 0;
        while (isdigit(chr)) {
            num = num * 10 + chr - '0';
            chr = getChar();
        }
        return sgn * num;
    }

public:
    InParser(const char* name) : str(1e5), ptr(str.size()), fin(name) { }
    ~InParser() { fin.close(); }

    template<class T>
    friend InParser& operator>>(InParser& in, T& num) {
        num = in.getInt<T>();
        return in;
    }
};

class OutParser {
    vector<char> str;
    int ptr;
    ofstream fout;

    void putChar(char chr) {
        if (ptr == int(str.size())) {
            fout.write(str.data(), str.size());
            ptr = 0;
        }
        str[ptr++] = chr;
    }

    template<class T>
    void putInt(T num) {
        if (num < 0) {
            putChar('-');
            num *= -1;
        }
        if (num > 9)
            putInt(num / 10);
        putChar(num % 10 + '0');
    }

public:
    OutParser(const char* name) : str(1e5), ptr(0), fout(name) { }
    ~OutParser() { fout.write(str.data(), ptr); fout.close(); }

    template<class T>
    friend OutParser& operator<<(OutParser& out, const T num) {
        out.putInt(num);
        return out;
    }

    friend OutParser& operator<<(OutParser& out, const char chr) {
        out.putChar(chr);
        return out;
    }

    friend OutParser& operator<<(OutParser& out, const char* str) {
        for (int i = 0; str[i]; i++)
            out.putChar(str[i]);
        return out;
    }
};


InParser fin("cuplaj.in");
OutParser fout("cuplaj.out");

vector <pair <int, int>> cty[57917];
const int mod = 57917;
int tata[20002];
vector <vector<int>> adjL;
vector  <int> viz;
int n1, n2, m, i, nr1, nr2, nr3, minn, j;

void bagHash(int nr, int val){
    int clasa = nr % mod;
    for (int j = 0; j < cty[clasa].size(); ++j){
        if (cty[clasa][j].first == nr){
            cty[clasa][j].second = val;
            return;
        }
    }
    cty[clasa].push_back({nr, val});
}

int cautHash(int nr){
    int clasa = nr % mod;
    for (int j = 0; j < cty[clasa].size(); ++j){
        if (cty[clasa][j].first == nr)
            return cty[clasa][j].second;
    }
    return 0;
}

int BFS(){
	queue<int> q;
	q.push(0);
	viz.assign(n1+n2+2, 0);
	viz[0] = 1;
	while(!q.empty()){
		nr1 = q.front();
		q.pop();
		if(nr1 == n1+n2+1)
			break;
		for(auto &i : adjL[nr1]){
		    nr3 = i;
            nr2 = cautHash(nr1 + i * 20001);
			if (!viz[i] && nr2 != 0){
				viz[i] = 1;
                if (nr2 == -1)
                    tata[i] = -nr1;
                else
                    tata[i] = nr1;
				q.push(i);
			}
		}
	}
	return viz[n1+n2+1];
}


int main(){
  	fin >> n1 >> n2 >> m;
  	adjL.assign(n1+n2+2, vector<int>());
  	for(i = 0; i < m; ++i){
  		fin >> nr1 >> nr2;
  		adjL[nr1].push_back(nr2+n1);
  		adjL[nr2+n1].push_back(nr1);
  		bagHash(nr1 + (nr2+n1) * 20001, 1);
  	}
    //cout << n1 << '\n';
  	for (i = 1; i <= n1; ++i){
        adjL[0].push_back(i);
        adjL[i].push_back(0);
        //cout << adjL[0].size() << '\n';
        bagHash(0 + i * 20001, 1);
  	}
  	//cout << adjL[0].size() << ' ';
  	for (i = n1+1; i <= n1+ n2 ; ++i){
        adjL[i].push_back(n1+n2+1);
        adjL[n1+n2+1].push_back(i);
        bagHash(i + (n1+n2+1)*20001, 1);
  	}
  	vector<pair <int, int>> rez;
  	while(BFS()){
  		for(auto &i:adjL[n1+n2+1]){
            minn = 1;
  			tata[n1+n2+1] = i;
  			for (j = n1+n2+1; j> 0;){
                if (tata[j] < 0){
                    minn = min(minn, -cautHash(-tata[j] + j * 20001));
                    j = -tata[j];
                }
  				else{
                    minn = min(minn, cautHash(tata[j] + j * 20001));
                    j = tata[j];
  				}
  			}
  			for (j = n1+n2+1; j> 0;){
                if (tata[j] < 0){
                    bagHash(-tata[j] + j * 20001, cautHash(-tata[j] + j * 20001) + minn);
                    bagHash(j + (-tata[j]) * 20001, cautHash(j + (-tata[j]) * 20001) + minn);
                    j = -1 * tata[j];
                }
  				else{
                    bagHash(tata[j] + j * 20001, cautHash(tata[j] + j * 20001) - minn);
                    bagHash(j + tata[j] * 20001, cautHash(j + tata[j] * 20001) - minn);
                    j = tata[j];
  				}
  			}
  		}
  	}
  	for(i=1; i<= n1; ++i){
        for(auto &k : adjL[i]){
            if (cautHash(i+ k * 20001) == 0 && k != 0){
                rez.push_back({i, k-n1});
            }
        }
  	}
  	fout << rez.size() << "\n";
  	for( auto & k : rez)
        fout << k.first << " " << k.second << '\n';

	return 0;
}