Cod sursa(job #57303)

Utilizator gigi_becaliGigi Becali gigi_becali Data 1 mai 2007 18:23:14
Problema Felinare Scor 22
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.72 kb
using namespace std;

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

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

#define maxn 8192


#ifndef NDEBUG
int stp;
#endif



vector<vector<int> > x;
vector<vector<bool> > a;
//char aa[maxn+2000][(maxn/8) +2000];

struct nod { int x, y;nod(){}; nod(int a, int b){x=a; y=b;};};

int n, m, E;
int source, sink;
int t[maxn<<1];
int d[maxn<<1];
bool Viz[maxn<<1];
int bfs();
void solve();

void read()
{

	int i,p, q;
		scanf("%d %d\n", &n, &m);
		a.clear();
		x.clear();
		
		a.resize(n+n+2);
		for(i=0;i<n+n+2;i++) a[i].resize(n+n+2);
		source=0;
		sink=n+n+1;
		x.resize(n+n+2);
		for(i=0;i<m;++i)
		{
			scanf("%d %d\n", &p, &q);
			if(!a[p][q+n])
			  {
			    a[p][q+n]=1;
 
			    x[p].push_back(q+n);
			    x[q+n].push_back(p);
			  }
			
		}
		for(i=1;i<=n;++i)a[source][i]=1, x[source].push_back(i), x[i].push_back(source);
		for(i=n+1;i<sink;++i) a[i][sink]=1, x[i].push_back(sink), x[sink].push_back(i);
		
		

		
}


int bfs()
{
	int Q[maxn<<1], p=1, q=1;
		bool viz[maxn<<1];
		//int d[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;
	int i;
	vector<int>::iterator it, xu;
	
	while(p<=q)
	{
		u=Q[p++];
		xu=x[u].end();
		for(it=x[u].begin();it!=xu;++it)
		{
		  i=*it;
		  if(!viz[i] && a[u][i])//(aa[u][(i)>>3]&(1<<((i)&7))))
			{
				viz[i]=1;
				d[i]=d[u]+1;
				//	t[i]=u;
				Q[++q]=i;
				//	if(i==sink) return d[i];
			}
		}
	}
	
	return d[sink];
}



int flow, ok=1, dsink,nr;
deque<nod>Q;

void dfs2(int nd, int nr)
{
	
  //    printf("%d %d\n",nd, nr);
	if(nr>dsink) return;

	if(nd==sink) { ++flow; ok=0; return;}
	
	
	Viz[nd]=1;

	vector<int>::iterator it, xnd;
	int i;
	xnd=x[nd].end();
	for(it=x[nd].begin(); it!=xnd; ++it)
	{
	   i=*it;
	   if(ok &&  !Viz[i]  && a[nd][i])
	     {

			 dfs2(i, nr+1);
			
			if(!ok)
			{
			  a[nd][i]=0;
			  a[i][nd]=1;
			  //	  Viz[i]=1;
			    if(nd==source) ok=1;
			    else
			      break;
			}
		
	     }
	}
}
	

void dfs(int nd)
{
 //if(nd!=sink) Viz[nd]=1;
 // printf("%d %d\n", nd, nr);
  if(nr>dsink) return;
  if(nd==sink && nr==dsink) { ++flow; ok=0; return;}
  Viz[nd]=1;
  vector<int>::iterator it;
 
  for(it=x[nd].begin();it!=x[nd].end();++it)
    if(ok && !Viz[*it] && a[nd][*it])
      {
	++nr;
	dfs(*it);
	--nr;
	if(!ok)
	  {
	    //  a[nd][*it]=0;
	    //a[*it][nd]=1;
	    Q.push_back(nod(nd, *it));
	    if(nd==source) ok=1;
	    else break;
	  }
      }
}


void DFS(int nd, int nr)
{
  if(nr>dsink) return;
  if(nd==sink) { ++flow; ok=0; return ;}
  Viz[nd]=1;
  vector<int>::iterator it;

  for(it=x[nd].begin();it!=x[nd].end();++it)
    if(d[nd]==d[*it]-1)
      if(ok && !Viz[*it] && a[nd][*it])
	{
	  DFS(*it, nr+1);
	  if(!ok)
	    {
	      a[nd][*it]=0;
	      a[*it][nd]=1;
	      //  Q.push_back(nod(nd, *it));
	      if(nd==source) ok=1;
	      else break;
	    }
	}
}


void solve()
{
	int i, j;
	int p;
	
	flow=0;
	vector<int>::iterator it;
	int num=0;
	int sq=(int)sqrt(n+n)+3;
	int ntimes=0;
	while(ntimes<sq)
	{	
		dsink=bfs();
		if(dsink==0) break;
		++ntimes;
	  ++num;
	//  printf("(%d)\n", dsink);
	  memset(Viz, 0, sizeof(Viz));
		ok=1;
		nr=0;
		//dsink=d[sink];	
	//	Viz[source]=1;
		//Q.clear();
		DFS(source, 0);
		//for(deque<nod>::iterator p=Q.begin();p!=Q.end();++p)
		// a[p->x][p->y]=0,
		// a[p->y][p->x]=1;

	}
	printf("%d\n", 2*n-flow);
	//printf("%d %d %d\n",(int) sqrt(n), nr, n);
		//printf("(%d)\n", n);
	//	printf("(%d)\n", (int)sqrt(n+n)+3);
	//printf("(%d)\n", num);
}






int main()
{
  //   freopen("fel.in", "r", stdin);
   freopen(FIN, "r", stdin);
	    	freopen(FOUT, "w", stdout);

	read();
	solve();
	
	return 0;
}