uva 11324

来源:互联网 发布:linux解析文件 编辑:程序博客网 时间:2024/06/03 06:02
这是有向图的最大团问题 ,  解决方法是:先求出scc的dag图,再用dag动态规划来求最大团

#include
#include
#include
#include
#include
#include
using namespace std;

const int MAXN = 1100 ;

int pre[MAXN] , lowlink[MAXN] , sccno[MAXN] ;
int n = 0, m = 0, dfs_clock = 0, scc_cnt = 0 , vis[MAXN];
vector grap[MAXN] ;
stack s;
int d[MAXN] , scc_sum[MAXN];
int DAG[MAXN][MAXN];


void dfs(int u)
{
    lowlink[u] =pre[u] = ++dfs_clock ;
   s.push(u);
    for(int i =0 ; i < grap[u].size() ; i++)
    {
       int v =grap[u][i] ;
      if(!pre[v])
       {
          dfs(v);
          lowlink[u] = min( lowlink[v] , lowlink[u]);
       }
       elseif(!sccno[v])
       {
           lowlink[u] = min(lowlink[u] , pre[v]) ;//在这里不是和lowlink[v]比较 ,是因为此时lowlink[v] == pre[v] 。
          //因为v这个点首先不属于其他任何一个强连通分量 , 所以就可以判断出v和u是的祖先 。 就是说dfs是先到达v , 然后再从v来到了u。
       }
    }
   if(lowlink[u] == pre[u]) 
    {
      scc_cnt++;
       for(;;)
       {
          int x =s.top();
          s.pop();
          sccno[x] =scc_cnt;
      //    sum +=1;
          if(x ==u)  break;
       }
   //   scc_sum[scc_cnt] = sum ;
    }
}


void find_scc()
{
    memset(pre ,0 , sizeof(pre));
   memset(lowlink , 0 , sizeof(lowlink));
    memset(sccno, 0 , sizeof(sccno));
   memset(scc_sum , 0 , sizeof(scc_sum));
    memset(vis ,0 , sizeof(vis));
    dfs_clock =scc_cnt = 0 ;
    for(int i =1; i <= n; i++)
      if(!pre[i])  dfs(i);
}


int dp(int v)

      
       if(d[v]) return d[v]; 
       int Max = 0; 
       for(int i = 1;i <= scc_cnt;i++) 
         if(DAG[v][i])
             Max =max(Max,dp(i)); 
       return d[v] = scc_sum[v] + Max; 
   


int main()
{
    int p;
   cin>>p;
   while(p--)
    {
       int i , j ,x , y;
       for(i = 1; i<= n ; i++)
         grap[i].clear();
      cin>>n>>m;
       for(i = 0 ;i < m; i++)
       {
          scanf("%d%d" , &x , &y);
         grap[x].push_back(y);
       }
      find_scc();
       for(i = 1; i<= n; i++)
         scc_sum[sccno[i]] += 1;
       memset(DAG ,0 , sizeof(DAG));
       for(i = 1; i<= n; i++)
          for(j = 0 ;j < grap[i].size() ; j++)
          {
             x =grap[i][j];
             if(sccno[i]!= sccno[x])  DAG[sccno[i]][sccno[x]] = 1;
          }
       memset(d , 0, sizeof(d));
       int max_sum= 0;
      
       for(i = 1; i<= scc_cnt; i++)
       {
          x =dp(i);
          if(x >max_sum)  max_sum = x ;
       }
      cout<<max_sum<<endl;
    }
    return0;
}


每次写代码时 , 都要谨慎、谨慎、再谨慎!!!
0 0
原创粉丝点击