大致思路和大白书上的相同,不过感觉书上的决策部分讲解的并不是非常清楚,因此我在这里讲解一下我的决策思路。
首先,d(i,j)表示根节点为i的子树,当它的父节点为j(j=0或1)时的x的最小值(x的含义书上有讲解),要将该子树根节点和父节点相连的边的情况计算在内。接下来遍历森林中的每一棵树,对于每一棵树的根节点进行特别的处理,然后就对该树进行深度优先搜索dfs(i)。
对于d[i][0]的情况,因为当前子树根节点i的父节点为0,所以该子树根节点的状态必为1,则d[i][0]=sum{d[k][1]|k为i的子节点}+M+1。然而,对于d[i][1]则需要分两种情况进行讨论:当i为1时,d1=sum{d[k][1]|k为i的子节点}+M,当i为0时,d0=sum{d[k][0]|k为i的子节点}+1,则d[i][1]=min(d0,d1)。最后每棵树的根节点都按照自身为1和自身为0,分别加上对于的sum{d[k][j]|k为对应根节点的子节点}即可。详细解答见代码。
#include
#include
#include
#include
#define MAX 1000+5
#define M 2000
using namespace std;
int T,n,m,x;
int G[MAX][MAX],vis[MAX],d[MAX][2];
void dfs(int);
int main()
{
cin>>T;
while(T--){
cin>>n>>m;
memset(G,0,sizeof(G));
x=0;
int a,b;
for(int i=0;i>a>>b;
G[a][b]=G[b][a]=1;
}
memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
for(int i=0;i