POJ - 3659-1463 (DP árbol que domina punto de consigna o cobertura mínima)

Tema: Click
preguntó cuántos puntos son el mínimo necesario ponerse en contacto con el árbol todos los puntos.
Mínimo conjunto dominante: Para la Figura G = <v, e>, el conjunto dominante mínimo se refiere a tomar hasta un punto de ajuste mínimo de la v, de modo que los puntos restantes V se toman con un bordes punto conectado. La figura v0 se proporciona un conjunto dominante, entonces para cualquier vértice en la Fig. U, v0 o bien pertenece al conjunto, o adyacente a la v0 vértice. Después de la eliminación de cualquier elemento ya no está dominando v0 conjunto v0, el conjunto dominante V0 es conjunto dominante mínima.

Del mismo modo punto de cobertura mínima, entonces, es todo lado de barrido de:
(adjuntar ejemplo aquí: POJ-1463 ) Vertex cobertura mínima. Fue sólo dos específicas ver el estado último código publicadas.

Dominado por un conjunto mínimo de palabras para hacer para establecer un estado:
dp [i] [0]: representa el punto centralizado no dominan, su nodo padre es el punto de enfoque dominante.
dp [i] [1]: indica que el punto de ajuste es dominante.
dp [i] [2]: representa un punto centralizado no domina, tiene nodos hijo Sí.
(Directamente codiciosos con conjunto dominante mínimo de la gráfica también es posible)
el título ha sido declarado como el árbol interrelacionado.
ecuación de transición directa del estado del árbol de Dp se puede establecer:
dp [I] [0]: indica el nodo padre del nodo ha sido manchado, la mancha puede ser o no el punto de tinción.
dp [i] [1]: Indica el punto de coloración directa, entonces el nodo hijo y el nodo padre puede elegir para no manchar o tinción.
dp [i] [2]: representa un nodo hijo tinción ese punto, pero necesita una gran cantidad de nodos secundarios para determinar un niño óptima. (Nodo padre del nodo punto niño no determina mancha, por lo que hay dos casos a juez)
Véase Código:

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<map>
#include<algorithm>
#include<queue>
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
int n;
vector<int>hh[10011];
int dp[10011][3];
bool vis[10011];
void dfs(int root,int f)
{
    if(root!=1&&hh[root].size()==1)
    {
        dp[root][2]=1e9+9;
        dp[root][0]=0;
        dp[root][1]=1;
        return ;
    }
    dp[root][1]=1;
    int MIN=1e9+10;
    bool flag=false;
    for(int i=0;i<hh[root].size();i++)
    {
        int v=hh[root][i];
        if(v==f)
            continue;
        dfs(v,root);
        dp[root][0]+=min(dp[v][1],dp[v][2]);//父亲节点如果已经染色  子节点可以染色 也可以不染色
        dp[root][1]+=min(dp[v][0],min(dp[v][1],dp[v][2]));//该节点如果已经染色 子节点父节点都可以选择染或者不染
        if(dp[v][1]>dp[v][2])//我有很多子节点我需要确定一个最优的子节点
        {
            dp[root][2]+=dp[v][2];
            MIN=min(MIN,dp[v][1]-dp[v][2]);
        }
        else
        {
            flag=true;
            dp[root][2]+=dp[v][1];
        }
    }
    if(!flag)//如果由于子节点的子节点染色情况比它好 没有一个子节点被染色了 必须要一个最好的来染色
    {
        dp[root][2]+=MIN;
    }
}
int main()
{
    memset(dp,0,sizeof(dp));
    int i,j,k;
    scanf("%d",&n);
    for(i=1;i<n;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        hh[x].push_back(y);
        hh[y].push_back(x);
    }
    if(n==1||n==2)
    {
        printf("1\n");
        return 0;
    }
    dfs(1,-1);
    printf("%d",min(dp[1][1],dp[1][2]));//因为已经把1看做一个根了
    return 0;
}

Capacidad-1463

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<map>
#include<algorithm>
#include<queue>
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
int n;
vector<int>hh[10011];
int dp[10011][2];
bool vis[10011];
int f[1600];
void dfs(int root)
{
    if(vis[root])
        return ;
    vis[root]=true;
    dp[root][0]=0;
    dp[root][1]=1;
    bool flag=false;
    for(int i=0;i<n;i++)
    {
        if(f[i]==root)
        {
            dfs(i);
            dp[root][1]+=min(dp[i][0],dp[i][1]);
            dp[root][0]+=dp[i][1];
        }
    }
}
int main()
{
    while(~scanf("%d",&n))
    {
            memset(dp,0,sizeof(dp));
            memset(f,-1,sizeof(f));
            memset(vis,false,sizeof(vis));
            int i,j,k;
            for(i=0;i<n;i++)
            {
                int xh,y;
                int num;
                scanf("%d:(%d)",&xh,&num);
                for(j=0;j<num;j++)
                {
                    scanf("%d",&y);
                    f[y]=xh;
                }
            }
            if(n==1)
            {
                printf("0\n");
                continue;
            }
            int root;
            for(i=0;i<n;i++)
            {
                if(f[i]==-1)
                    root=i;
            }
            dfs(root);
            printf("%d\n",min(dp[root][0],dp[root][1]));
    }
    return 0;
}

Publicado 72 artículos originales · ganado elogios 19 · vistas 7503

Supongo que te gusta

Origin blog.csdn.net/weixin_43958964/article/details/104433270
Recomendado
Clasificación