Cod sursa(job #29718)

Utilizator cypryCiprian Oprisa cypry Data 9 martie 2007 20:16:46
Problema Party Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.69 kb
#include<stdio.h>
#include<string.h>
#define NMAX 102

int n,v[NMAX],uz[NMAX],a[NMAX][NMAX],coada[NMAX];

void set_n(int *n,int k)
{
 int i,x=*n,y=0;
 for(i=1;i<k;++i)
  {
   y=2*y+x%2;
   x=x/2;
  }
 x=2*x+1;
 for(i=1;i<k;++i)
  {
   x=2*x+y%2;
   y=y/2;
  }
 *n=x;
}

int is_n(int n,int k)
{
 int i;
 for(i=1;i<k;++i)
  n/=2;
 return n%2;
}

void citire(void)
{
 int  i,m,x,y,z;
 scanf("%d %d",&n,&m);
 for(i=1;i<=m;++i)
  {
   scanf("%d %d %d",&x,&y,&z);
   if(!z) z=4;
   if(z>=3)
    {
     set_n(&a[x][y],z);
     set_n(&a[y][x],z);
    }else if(z==1) set_n(&a[y][x],1);
     else set_n(&a[x][y],1);
  }
}

int sol(int p)
{
 memset(v,0,NMAX*sizeof(int));
 memset(uz,0,NMAX*sizeof(int));
 memset(coada,0,NMAX*sizeof(int));
 v[p]=1;
 uz[p]=1;
 int i,x=0,y=1,k;
 coada[1]=p;
 while(x<y)
  {
   k=coada[++x];
   for(i=1;i<=n;++i)
    if(a[k][i])
     {
      if(is_n(a[k][i],3) && v[k])
       {
	if(v[i]) return 0;
	//v[i]=0;
	if(!uz[i])
	 {
	  uz[i]=1;
	  coada[++y]=i;
	 }
       }else if(is_n(a[k][i],4) && !v[k])
	{
	 if(uz[i] && !v[i]) return 0;
	 if(!uz[i])
	  {
	   v[i]=1;
	   uz[i]=1;
	   coada[++y]=i;
	  }
	}else if(!v[i] && v[k])
	 {
	  if(uz[i]) return 0;
	  v[i]=1;
	  uz[i]=1;
	  coada[++y]=i;
	 }
     }

  }
 return 1;
}

int solutie(void)
{
 int i=0,nr=0;
 do{++i;}while(!sol(i));
 for(i=1;i<=n;++i)
  nr+=v[i];
 return nr;
}

void afisare(void)
{
 int i;
 printf("%d\n",solutie());
 for(i=1;i<=n;++i)
  if(v[i]) printf("%d\n",i);
}

int main(void)
{
 freopen("party.in","r",stdin);
 freopen("party.out","w",stdout);
 citire();
 afisare();
 fclose(stdin);
 fclose(stdout);
 return 0;
}