Cod sursa(job #3181804)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 7 decembrie 2023 22:52:19
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.45 kb
// Acest cod este scris deoarece doresc sa testez un algoritm greedy pe
// care nu il pot demonstra si caruia nu ii pot gasi un contraexecmplu.
// Nu intentionez sa obtin 100 de puncte cu el.

// Ilie Dumitru
#include<cstdio>
#include<vector>
#include<bitset>
#include<queue>
const int NMAX=10005;

struct edge
{
	int node, pos;
};

struct el
{
	int node, deg;

	friend bool operator<(el a, el b)
	{
		return a.deg>b.deg;
	}
};

int N, M;
std::vector<edge> G[NMAX*2];
std::bitset<NMAX*2> matched;
std::vector<int> ans;

void addEdge(int a, int b)
{
	G[a].push_back({b, (int)G[b].size()});
	G[b].push_back({a, (int)G[a].size()-1});
}

void remove_edge(int a, int idx)
{
	int b=G[a][idx].node, bidx=G[a][idx].pos;
	int la=(int)G[a].size(), lb=(int)G[b].size();

	// G[a][idx]={b, bidx};
	// G[b][bidx]={a, idx};

	if(la-1!=idx)
	{
		G[G[a][la-1].node][G[a][la-1].pos].pos=idx;
	}
	if(lb-1!=bidx)
	{
		G[G[b][lb-1].node][G[b][lb-1].pos].pos=bidx;
	}

	std::swap(G[a][idx], G[a][la-1]);
	std::swap(G[b][bidx], G[b][lb-1]);

	G[a].resize(la-1);
	G[b].resize(lb-1);
}

void cuplajGreedy()
{
	std::priority_queue<el> pq;
	int i, a, b, min, minPos, x;

	for(i=0;i<N+M;++i)
		if(!G[i].empty())
			pq.push({i, (int)G[i].size()});

	while(!pq.empty())
	{
		a=pq.top().node;
		pq.pop();
		if(!matched[a] && (int)G[a].size())
		{
			minPos=0;
			min=(int)G[G[a][0].node].size();
			for(i=1;i<(int)G[a].size();++i)
			{
				if(min>(int)G[G[a][i].node].size())
				{
					minPos=i;
					min=(int)G[G[a][i].node].size();
				}
			}

			b=G[a][minPos].node;
			matched[a]=matched[b]=1;
			ans.push_back(a);
			ans.push_back(b);

			remove_edge(a, minPos);

			while((int)G[a].size())
			{
				x=G[a][0].node;
				remove_edge(a, 0);
				pq.push({x, (int)G[x].size()});
			}

			while((int)G[b].size())
			{
				x=G[b][0].node;
				remove_edge(b, 0);
				pq.push({x, (int)G[x].size()});
			}
		}
	}
}

int main()
{
	FILE* f=fopen("cuplaj.in", "r"), *g=fopen("cuplaj.out", "w");
	int i, a, b, E;

	fscanf(f, "%d%d%d", &N, &M, &E);
	for(i=0;i<E;++i)
	{
		fscanf(f, "%d%d", &a, &b);
		--a;
		--b;
		b+=N;

		addEdge(a, b);
	}

	cuplajGreedy();

	fprintf(g, "%d\n", (int)ans.size()/2);
	for(i=0;i<(int)ans.size();i+=2)
	{
		a=ans[i];
		b=ans[i+1];
		if(a<N)
			b-=N;
		else
		{
			std::swap(a, b);
			b-=N;
		}

		fprintf(g, "%d %d\n", a+1, b+1);
	}

	fclose(f);
	fclose(g);
	return 0;
}