Cod sursa(job #57470)

Utilizator gigi_becaliGigi Becali gigi_becali Data 2 mai 2007 10:24:13
Problema Felinare Scor 38
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.42 kb
using namespace std;

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <iostream>
#include <cmath>
#include <cassert>
#include <deque>
#include <ctime>
#define NDEBUG

#define FIN "felinare.in"
#define FOUT "felinare.out"

#define maxn 8192


#ifndef NDEBUG
int stp;
#endif

struct nod { short x, poz; bool cap; nod(){};  nod(short a, short b, bool c){x=a; poz=b; cap=c;};}__attribute__ ((packed));

nod *x[maxn<<1];
int len[maxn<<1];
int n, m, E;
short int source, sink;
//int t[maxn<<1];
short int d[maxn<<1];
bool Viz[maxn<<1];
short muchii[30000][2], g[maxn<<1];
int bfs();
void solve();

void read()
{

	int i,p, q;
		scanf("%d %d\n", &n, &m);

		source=0;
		sink=n+n+1;
		//x.resize(n+n+2);
		//poz.resize(n+n+2);
		//		short int muchii[300000][2], g[maxn<<1];
		memset(g, 0, sizeof(g));
		memset(muchii, 0, sizeof(muchii));
		int num=0;
		for(i=0;i<m;++i)
		{
			scanf("%d %d\n", &p, &q);  


			++g[p]; ++g[q];
			muchii[++num][0]=p;
			muchii[num][1]=q+n;
			/*
			x[p]=(nod*)realloc(x[p], sizeof(nod)*(len[p]+20));
			x[q+n]=(nod*)realloc(x[q+n], sizeof(nod)*(len[q+n]+20));
			
			x[p][len[p]++]=nod(q+n, len[q+n], 1);
			x[q+n][len[q]++]=nod(p, len[p]-1, 0);
			*/

			//			x[p].push_back(nod(q+n, x[q+n].size(), 1));
			//x[q+n].push_back(nod(p, x[p].size()-1, 0));
		}

		
		for(i=1;i<=n;++i)
		  {

		    ++g[source]; ++g[i];
		    muchii[++num][0]=source;
		    muchii[num][1]=i;
		    /*
		    x[source]=(nod*)realloc(x[source], sizeof(nod)*(len[source]+20 ));
		      //rintf("%d %d\n", i, len[i]);
		      x[i]=(nod*) realloc(x[i],sizeof(nod)*(len[i]+20));

		     x[source][len[source]++]=nod(i, len[i], 1);
		    x[i][len[i]++]=nod(source, len[source]-1, 0);
		    */
		    //		    x[source].push_back(nod(i, x[i].size(), 1));
		    //x[i].push_back(nod(source, x[source].size()-1, 0));
		  }		    
		
		
		for(i=n+1;i<sink;++i) 
		  {
		    ++g[i];
		    ++g[sink];
		    muchii[++num][0]=i;
		    muchii[num][1]=sink;

		    /*
		    x[i]=(nod*) realloc(x[i],  sizeof(nod)*(len[i]+20));
		    x[sink]=(nod*)realloc(x[sink], sizeof(nod)*(len[sink]+20));
		    
		    x[i][len[i]++]=nod(sink, len[sink], 1);
		    x[sink][len[sink]++]=nod(i, len[i]-1, 0);
		    
		    //x[i].push_back(nod(sink, x[sink].size(), 1));
		    //x[sink].push_back(nod(i, x[i].size()-1, 0));
		    */
		    }
		
		//	for(i=0;i<=sink;++i) printf("%d ", g[i]);
		//printf("%d %d\n", source, sink);
		
		for(i=source;i<=sink;++i) x[i]=new nod[g[i]+20];///(nod*) malloc(sizeof(nod)*(g[i]+20));

		
		//printf("%d\n", num);
		for(i=1;i<=num;++i)
		  {
		    int p, q;
		    p=muchii[i][0];
		    q=muchii[i][1];
		    //printf("(%d %d)\n", p, q);
		    x[p][len[p]++]=nod(q, len[q], 1);
		    x[q][len[q]++]=nod(p, len[p]-1, 0);
		  }
		for(i=source;i<=sink;++i) x[i][len[i]].x=-1;
		
}


int bfs()
{
	short Q[maxn<<1], p=1, q=1;
	bool viz[maxn<<1];
		
	memset(viz, 0,sizeof(viz));
	//memset(t, -1, sizeof(t));
	memset(d, 0, sizeof(d));
	viz[source]=1;
	Q[1]=source;
	d[1]=0;
	int u;
	short i, j;
	//vector<nod>::iterator it,jt, xu;
	nod *it;

	while(p<=q)
	{
		u=Q[p++];
			//xu=x[u].end();
		//printf("%d\n", u);
		for(it=x[u]; (it->x)!=-1 ; ++it)
		  //for(it=x[u].begin() ;it!=xu;++it)
		{
		 i=it->x; 
		  if(!viz[i]&& (it->cap)) //(aa[u][(i)>>3]&(1<<((i)&7))))
			{
				viz[i]=1;
				d[i]=d[u]+1;
				Q[++q]=i;
			       
			}
		}
	}
	
	return d[sink];
}



int flow, ok=1, dsink,nr;
int counter;

void DFS(short nd, short nr)
{
  

  //printf("%d %d\n", nd, nr);
  if(nr>dsink) return;
  if(nd==sink) { ++flow; ok=0; return ;}
  Viz[nd]=1;
  //vector<nod>::iterator it;
  nod *it;

  for(it=x[nd] ; (it->x)!=-1 ;++it)
    if(nr==d[it->x]-1)
     {
      
       if( ok && !Viz[it->x] && (it->cap) )   //(aa[nd][i>>3]&(1<<(i&7))))//a[nd][i])
	{
	  //++nr;
	  DFS(it->x, nr+1);
	  //--nr;
	  if(!ok)
	    {
	     	it->cap=0;
		x[it->x][it->poz].cap=1;
		if(nd==source) ok=1;
		else break;
	    }
	}
     }
}


void solve()
{
	int i, j;
	int p;
	
	flow=0;
	
	while(dsink=bfs())
	{	

	 
	  memset(Viz, 0, sizeof(Viz));
	  ok=1;
	  nr=0;
	 
	  DFS(source, 0);
	 
		
      	}
	printf("%d\n", 2*n-flow);
	
}


int main()
{
  //  freopen("fel.in", "r", stdin);
  freopen(FIN, "r", stdin);
      
	freopen(FOUT, "w", stdout);
      
	  read();
  
	  solve();
  
  int i, j;
  /*  
  for(i=source;i<=sink;++i)
    {
      for(nod *p=x[i]; (p->x)!=-1; ++p) printf("(%d %d %d) ", p->x, p->poz, p->cap);
      // for(j=0;j<len[i];++j) printf("%d ", x[i][j].x);
      printf("\n");
    }
  */
	
	return 0;
}