Cod sursa(job #390992)

Utilizator lorandCsorba Lorand-Alexandru lorand Data 4 februarie 2010 21:35:59
Problema Componente tare conexe Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.72 kb
using namespace std;
#include<fstream>
struct nod
{
       int vf;
       nod*  next;
};
int n,m,t,comp,*v,*ord,*final,*pluss,*minuss,*coada,*viz;
nod   *G[100005],*U[100005],*Gt[100005],*Ut[100005];
void addarc(int,int);
void DFS(int);
int main()
{
    nod *p;
    int i,x,y,s,d;
    ifstream fin("ctc.in");
    fin>>n>>m;
    for(i=1;i<=m;++i)
    {
                     fin>>x>>y;
                     addarc(x,y);
    }
    v=new int[n+1];
    for(i=1;i<=n;++i)
       v[i]=0;
    final=new int[n+1];
    t=n+1;
    for(i=1;i<=n;++i)
       if(v[i]==0)
         DFS(i);
    ord=new int[n+1];
    for(i=1;i<=n;++i)
    {
                     x=final[i];
                     ord[n-x+1]=i;
    }
    for(i=1;i<=n;++i)
       v[i]=0;
    pluss=new int[n+1];
    minuss=new int[n+1];
    coada=new int[n+1];
    viz=new int[n+1];
    for(i=1;i<=n;++i)
    {
                     x=ord[i];
                     if(v[x]==0)
                     {
                                for(y=1;y<=n;++y)
                                   viz[y]=pluss[y]=0;
                                s=d=1;
                                coada[d]=x;
                                while(s<=d)
                                {
                                           pluss[coada[s]]=1;
                                           for(p=G[coada[s]];p;p=p->next)
                                              if(viz[p->vf]==0)
                                              {
                                                           viz[p->vf]=1;
                                                           coada[++d]=p->vf;
                                              }
                                           ++s;
                                }
                                for(y=1;y<=n;++y)
                                   viz[y]=minuss[y]=0;
                                s=d=1;
                                coada[d]=x;
                                while(s<=d)
                                {
                                           minuss[coada[s]]=1;
                                           for(p=Gt[coada[s]];p;p=p->next)
                                              if(viz[p->vf]==0)
                                              {
                                                               viz[p->vf]=1;
                                                               coada[++d]=p->vf;
                                              }
                                           ++s;
                                }
                                ++comp;
                                for(y=1;y<=n;++y)
                                   if(pluss[y]*minuss[y])
                                   {
                                                         v[y]=comp;
                                   }
                     }
    }
    ofstream fout("ctc.out");
    fout<<comp<<'\n';
    for(i=1;i<=comp;++i)
    {
                        for(x=1;x<=n;++x)
                           if(v[x]==i)
                             fout<<x<<' ';
                        fout<<'\n';
    }
    return 0;
}
void addarc(int i,int j)
{
     nod *p=new nod;
     p->vf=j;
     p->next=NULL;
     if(U[i])
     {
             U[i]->next=p;
             U[i]=p;
     }
     else
     {
         G[i]=p;
         U[i]=p;
     }
     nod *q=new nod;
     q->vf=i;
     q->next=NULL;
     if(Ut[j])
     {
              Ut[j]->next=q;
              Ut[j]=q;
     }
     else
     {
         Gt[j]=q;
         Ut[j]=q;
     }
}
void DFS(int k)
{
     nod *p;
     v[k]=1;
     final[k]=--t;
     for(p=G[k];p;p=p->next)
        if(v[p->vf]==0)
          DFS(p->vf);
}