这是有向图的最大团问题 , 解决方法是:先求出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]
);
}
else
if(!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;
}
return
0;
}
每次写代码时 , 都要谨慎、谨慎、再谨慎!!!
#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)
{
}
void find_scc()
{
}
int dp(int v)
{
int main()
{
}
每次写代码时 , 都要谨慎、谨慎、再谨慎!!!