Cod sursa(job #1985009)

Utilizator raulmuresanRaul Muresan raulmuresan Data 26 mai 2017 17:49:03
Problema Cuplaj maxim in graf bipartit Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.71 kb
#include<fstream>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");

vector<int> g[10009];
vector<int> gt[10009];
int n, m;
int booksGiven = 0;
int gradExt[10009];
int gradInt[10009];
int bookGiven[10009];
int queueViz[10009];

struct persBook {
	int person;
	int grade;
};

struct cmp
{
	bool operator() (persBook x, persBook y)
	{
		return x.grade > y.grade;
	}
};
priority_queue<persBook, vector <persBook>, cmp> q;


void printQueue() {
	/*while (!q.empty()) {
		fout << q.top() << " ";
		q.pop();
	}*/
}

void read() {
    int e;
	fin >> n >> m >> e;
	int a, b;
	for (int i = 1; i <= e; i++) {
		fin >> a >> b;
		g[a].push_back(b);
		gt[b].push_back(a);
		gradExt[a]++;
		gradInt[b]++;
	}

	for (int i = 1; i <= n; i++) {
		q.push(persBook{ i, gradExt[i] });
	}
}

void solve() {
	while (!q.empty()) {
		//get current node
		persBook currentPair = q.top();
		q.pop();
		//fout << currentPair.person<<"\n";

		if (queueViz[currentPair.person] == 0) {
            int current = currentPair.person;

            //get first unvisited neighbour
            int next = -1;
            int gradMinim = 10000000;
            for (int j = 0; j < g[current].size(); j++) {
                if (gradInt[g[current][j]] < gradMinim && bookGiven[g[current][j]] == 0) {
                    next = g[current][j];
                    gradMinim = gradInt[g[current][j]];
                }
            }

            //try to advance ; available book + current not visited before
            if (next != -1 && queueViz[current] == 0) {

                //mark as visited by queue
                queueViz[current] = 1;

                //mark neighbour as visited
                bookGiven[next] = current;

                //for each node with -> to next ; decrease external grade and reinsert into queue
                for (int i = 0; i < gt[next].size(); i++) {
                    int neighbour = gt[next][i];
                    gradExt[neighbour]--;

                    q.push(persBook{ neighbour, gradExt[neighbour] });

                }
                for(int i = 0; i < g[current].size(); i++)
                {
                    gradInt[g[current][i]]--;
                }
            }

		}


	}

	int nr = 0;
	bool ok = true;
	for (int i = 1; i <= m; i++) {
        if(bookGiven[i] != 0)
        {
            nr++;
        }
	    //fout << bookGiven[i]<<" ";
	}
	fout << nr << "\n";
	for (int i = 1; i <= m; i++) {
        if(bookGiven[i] != 0)
        {
            fout << bookGiven[i] << " " << i <<"\n";
        }
	}

}

int main() {
	read();
	solve();
}