Cod sursa(job #563252)

Utilizator CipaFlorescu Ciprian Cipa Data 24 martie 2011 20:24:20
Problema Cuplaj maxim in graf bipartit Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.41 kb
#include<cstdio>
#include<cstdlib>
#include<vector>
using namespace std;

struct edge
{
	int from;
	int to;
	int cost;
	int index;
};
vector<bool> l,r;
vector<edge> edges,usedEdges;
int n,m,e,cost;


void insert_to_used(edge newEdge)
{
	if(r[newEdge.to])
	{
		for(int i=0;i<usedEdges.size();i++)
			if(usedEdges[i].to == newEdge.to)
				if(newEdge.cost < usedEdges[i].cost)
				{
					usedEdges[i] = newEdge;
					return;
				}
	}
	else
	{
		r[newEdge.to] = true;
		usedEdges.push_back(newEdge);
	}
}
			
int compare_edge(const void *a, const void*b)
{
	if(((edge*)a)->from == ((edge*)b)->from)
		return ((edge*)a)->cost - ((edge*)b)->cost;
	return ((edge*)a)->from - ((edge*)b)->from;
}

void read()
{
	int f,t,c=0;
	edge newEdge;
	for(int i=1;i<=e;++i)
	{
		scanf("%d %d",&f,&t);
		newEdge.from = f;
		newEdge.to = t;
		newEdge.cost = c;
		newEdge.index = i;
		edges.push_back(newEdge);
	}
	qsort(&edges[0],e,sizeof(edge),compare_edge);
}

bool reduce()
{
	int k = -1;
	bool change = false;
	for(int i=1;i<=n;i++)
	{
		int j=0;
		while(edges[++k].from == i && k < edges.size())
			j++;
		
		if(!l[i] && j<=1)
		{
			
			l[i] = true;
			if(j==1)
			{
				change = true;
				insert_to_used(edges[k-1]);
				cost += edges[k-1].cost;
				edges.erase(edges.begin()+k-1);
				k--;
			}
		}
		k--;
	}
	
	for(int i=0;i<edges.size();i++)
	{
		if(r[edges[i].to] && !l[edges[i].from])
		{
			edges.erase(edges.begin() + i);
			change = true;
		}
	}
	return change;			
}

bool check_reduce(vector<edge> ed,int index)
{
	for(int i=0;i<ed.size();i++)
		if(ed[index].to == ed[i].to && index != i)
			return false;
	
	return true;
}

void reduce_more(int i)
{
	if(i>=edges.size())
		return;
	int node = edges[i].from;
	if(check_reduce(edges,i))
	{
		insert_to_used(edges[i]);
		cost += edges[i].cost;
		while(edges[i].from == node && i<edges.size())
		{
			edges.erase(edges.begin() + i);
		}
	}
	while(edges[i].from == node && i<edges.size())
		i++;
		
	reduce_more(i);
		
}

int main()
{
	freopen("cuplaj.in","r",stdin);
	freopen("cuplaj.out","w",stdout);
	scanf("%d %d %d",&n,&m,&e);
	cost = 0;
	l.resize(n+5,0);
	r.resize(m+5,0);
	read();
	while(reduce());
	reduce_more(0);
	
	/*printf("remaining: \n");
	for(int i=0;i<edges.size();i++)
		printf("%d %d %d %d\n",edges[i].from, edges[i].to, edges[i].cost, edges[i].index);
		
	printf("solution:\n");*/
	printf("%d\n",usedEdges.size());
	for(int i=0;i<usedEdges.size();i++)
		printf("%d %d\n",usedEdges[i].from,usedEdges[i].to);
		
}