bzoj2466 [中山市选2009]树

题目描述:

bz

题解:

(1)高消。

直接列异或方程组高消即可。

代码:

#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 105;
template<typename T>
inline void read(T&x)
{
    T f = 1,c = 0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
    x = f*c;
}
int n,a[N][N];
void gs()
{
    for(int i=1;i<=n;i++)
    {
        int tmp = i;
        for(int j=i+1;j<=n;j++)
            if(a[j][i]>a[tmp][i])tmp=j;
        if(!a[tmp][i])continue;
        if(tmp!=i)
            for(int j=i;j<=n+1;j++)swap(a[i][j],a[tmp][j]);
        for(int j=1;j<=n;j++)if(j!=i&&a[j][i])
            for(int k=i;k<=n+1;k++)a[j][k]^=a[i][k];
    }
}
int ans;
void dfs(int u,int now)
{
    if(now>=ans)return ;
    if(!u)
    {
        ans = now;
        return ;
    }
    if(a[u][u])dfs(u-1,now+a[u][n+1]);
    else
    {
        if(a[u][n+1])return ;
        dfs(u-1,now);
        for(int i=u-1;i>=1;i--)a[i][n+1]^=a[i][u];
        dfs(u-1,now+1);
        for(int i=u-1;i>=1;i--)a[i][n+1]^=a[i][u];
    }
}
int main()
{
    while(1)
    {
        read(n);
        if(!n)break;
        memset(a,0,sizeof(a));
        for(int f,t,i=1;i<n;i++)
        {
            read(f),read(t);
            a[f][t]=a[t][f]=1;
        }
        for(int i=1;i<=n;i++)
            a[i][i]=a[i][n+1]=1;
        gs();
        ans = 0x3f3f3f3f;
        dfs(n,0);
        printf("%d\n",ans);
    }
    return 0;
}
高消

(2)树形$dp$。

设状态$dp[x][0/1][0/1]$表示:点$x$按/不按,子树内其他节点全亮,自己亮/不亮的最小代价。

代码:

#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 105;
const int inf = 0x3f3f3f3f;
template<typename T>
inline void read(T&x)
{
    T f = 1,c = 0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
    x = f*c;
}
int n,hed[N],cnt;
struct EG
{
    int to,nxt;
}e[2*N];
void ae(int f,int t)
{
    e[++cnt].to = t;
    e[cnt].nxt = hed[f];
    hed[f] = cnt;
}
int dp[N][2][2];
void dfs(int u,int f)
{
    dp[u][0][0]=0,dp[u][1][1]=1,dp[u][1][0]=dp[u][0][1]=n+1;
    for(int j=hed[u];j;j=e[j].nxt)
    {
        int to = e[j].to;
        if(to==f)continue;
        dfs(to,u);
        int d00 = dp[u][0][0],d01 = dp[u][0][1],d10 = dp[u][1][0],d11 = dp[u][1][1];
        dp[u][0][0] = min(d00+dp[to][0][1],d01+dp[to][1][1]);
        dp[u][0][1] = min(d00+dp[to][1][1],d01+dp[to][0][1]);
        dp[u][1][0] = min(d10+dp[to][0][0],d11+dp[to][1][0]);
        dp[u][1][1] = min(d10+dp[to][1][0],d11+dp[to][0][0]);
    }
}
int main()
{
    while(1)
    {
        read(n);
        if(!n)break;
        memset(hed,0,sizeof(hed));
        cnt = 0;
        for(int f,t,i=1;i<n;i++)
        {
            read(f),read(t);
            ae(f,t),ae(t,f);
        }
        dfs(1,0);
        printf("%d\n",min(dp[1][1][1],dp[1][0][1]));
    }
    return 0;
}
dp

 

posted @ 2019-04-24 18:12  LiGuanlin  阅读(216)  评论(0编辑  收藏  举报