题目大意:
就是输入一棵树,求出最大独立集的节点数目,然后至于怎么输入的话,先输入一个n,代表节点数目,然后输入n-1条边;
基本思路:
很显然,树形dp的话是最佳选择了吧,然后状态转移方程就是d(i) = max ( 1+Σd(j) , Σd(k) ) ( j∈gs(i) , i∈s(i) ),然后一切就简单了;
代码如下:
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 100+10;
struct Node
{
int to,next;
}node[maxn*2];
int cnt;
int head[maxn];
void AddEdge(int u,int v)
{
node[cnt].to=v;
node[cnt].next=head[u];
head[u]=cnt++;
}
int d[maxn],s[maxn],gs[maxn];
int dfs(int son,int dad)
{
for(int i=head[son];i!=-1;i=node[i].next)
{
int t=node[i].to;
if(t!=dad) dfs(t,son);
s[son]+=d[t];
if(dad!=-1) gs[dad]+=d[t];
}
d[son]=max(s[son],gs[son]+1);
return d[son];
}
int main()
{
int n;
while(scanf("%d",&n)==1)
{
cnt=0;
memset(d,0,sizeof(d));
memset(s,0,sizeof(s));
memset(gs,0,sizeof(gs));
memset(head,-1,sizeof(head));
for(int i=0;i<n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
AddEdge(u,v);
AddEdge(v,u);
}
printf("%d\n",dfs(n,-1));
}
}
//以上是我用数组实现邻接表写的正确的程序;
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 100
vector<int> v[maxn];
int d[maxn], s[maxn], gs[maxn];
int dfs(int n, int fa)
{
for(int i = 0; i < v[n].size(); i++)
{
int m = v[n][i];
if(m != fa)dfs(m, n);
s[n] += d[m];
if(fa != -1)
gs[fa] += d[m];
}
d[n] = max(s[n], gs[n] + 1);
return d[n];
}
int main()
{
// freopen("in.txt", "r", stdin);
int n;
while(cin >> n)
{
for(int i = 0; i < n; i++)
v[i].clear();
for(int i = 0; i < n-1; i++)
{
int a, b;
cin >> a >> b;;
v[a].push_back(b);
v[b].push_back(a);
}
memset(d, 0, sizeof(d));
memset(s, 0, sizeof(s));
memset(gs, 0, sizeof(gs));
cout << dfs(i, -1) << endl;
}
return 0;
}
//也不知道是什么原因,这个在我的编译器上第一次是正确的,多组输入就错了,蜜汁bug,我感觉没错的啊,有空再弄弄;