dp【0】【i】表示第i个不取得最大值
dp【1】【i】表示第i个取得最大值
注意各个点组成的可能是森林,要多次dfs
AC代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAX_N = 1100;
struct Edge{
int to, next;
};
int head[MAX_N], tot;
Edge edge[MAX_N*8];
int N, M;
int dp[2][MAX_N];
bool mark[MAX_N];
void add_edge( int a, int b ){
edge[tot].to = b;
edge[tot].next = head[a];
head[a] = tot++;
edge[tot].to = a;
edge[tot].next = head[b];
head[b] = tot++;
}
int DFS( int pre, int now_st, int pos ){
if( dp[now_st][pos] != -1 ){
return dp[now_st][pos];
}
mark[pos] = true;
dp[now_st][pos] = now_st;
for( int i = head[pos]; i != -1; i = edge[i].next ){
int to = edge[i].to;
if( to == pre ) continue;
if( now_st == 0 ){
dp[now_st][pos] += max( DFS( pos, 0, to ), DFS( pos, 1, to ) );
}else{
dp[now_st][pos] += DFS( pos, 0, to );
}
}
return dp[now_st][pos];
}
int main(){
int T, Case = 1;
scanf( "%d", &T );
while( T-- ){
scanf( "%d%d", &N, &M );
memset( head, -1, sizeof( head ) );
tot = 0;
for( int i = 0; i < M; i++ ){
int temp1, temp2;
scanf( "%d%d", &temp1, &temp2 );
add_edge( temp1, temp2);
}
memset( dp, -1, sizeof( dp ) );
memset( mark, false, sizeof( mark ) );
int ans = 0;
for( int i = 1; i <= N; i++ ){
if( !mark[i] ){
ans += max( DFS( -1, 0, i ), DFS( -1, 1, i ) );
}
}
printf( "Case %d: %d\n", Case++, ans );
}
return 0;
}
/*
4
6 5
1 2
2 3
3 4
3 6
2 5
4 2
3 4
1 2
anwser : 4, 2
*/