【P2016】战略游戏(贪心||树状DP)

这个题真是。。。看了一会之后,发现有一丝丝的熟悉,再仔细看了看,R,这不是那个将军令么。。。然后果断调出来那个题,还真是,而且貌似还是简化版的。。。于是就直接改了改建树和输入输出直接交了。。阿勒,就20分。。真是不给面子,于是就继续简化了代码。。。然后又交,变0分了。发现建树的时候双向边里面放了顺序一样的字母。。再改过来,A了,然而树形DP做法还未可知。。或许蒟蒻我就只能贪心吧。。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define re register
using namespace std;
struct po
{
    int next;
    int to;
    int dis;
};
po edge[1000001];
int head[1000001],b[1000001],temp[1000001],dis[1000001],f[1000001];
int T,s,t,n,m,x,w,a,l,num,flag,ans,visit[1000001],k;
inline int read() {
    char ch=' ';
    int w=1,x=0;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')w=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*w;
}
inline void add_edge(int from,int to,int dis)
{
    edge[++num].next=head[from];
    edge[num].to=to;
    edge[num].dis=1;
    head[from]=num;
}
inline void dfs(int x,int fa)
{
    temp[++l]=x;
    for(re int i=head[x];i;i=edge[i].next)
    if(edge[i].to!=fa)
    dfs(edge[i].to,x);
}
int main()
{
    cin>>n;
    k=1;    
    for(re int i=1;i<=n;i++)
    {
        s=read();
        s++;
        m=read();
        for(re int j=1;j<=m;j++)
        {
            t=read();
            t++;
            add_edge(s,t,1);
            add_edge(t,s,1);
            f[t]=s;
        }
    }
    dfs(1,0);
    for(re int i=n;i>=2;i--)
    if(!b[temp[i]]&&!b[f[temp[i]]])
    b[f[temp[i]]]=1;
    for(re int i=1;i<=n;i++)
    if(b[i])
    ans++;
    cout<<ans;
}

给出树状DP做法:

#include<iostream>
#include<cstdio>
#include<cstring>
#define re register
using namespace std;
struct po
{
    int next;
    int to;
    int dis;
};
po edge[1000001];
int head[1000001],b[1000001],temp[1000001],dis[1000001],f[1501][3];
int T,s,t,n,m,x,w,a,l,num,flag,ans=987654321,visit[1000001],k;
inline int read() {
    char ch=' ';
    int w=1,x=0;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')w=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*w;
}
inline void add_edge(int from,int to,int dis)
{
    edge[++num].next=head[from];
    edge[num].to=to;
    edge[num].dis=1;
    head[from]=num;
}
inline void dfs(int x,int fa)
{
    f[x][1]=1;f[x][0]=0;
    for(re int i=head[x];i;i=edge[i].next)
    {
        int u=edge[i].to;
        if(u!=fa)
        {
            dfs(u,x);
            f[x][1]+=min(f[u][1],f[u][0]);
            f[x][0]+=f[u][1];
        }
    }
}
int main()
{
    cin>>n;
    k=1;    
    for(re int i=1;i<=n;i++)
    {
        s=read();
        s++;
        m=read();
        for(re int j=1;j<=m;j++)
        {
            t=read();
            t++;
            add_edge(s,t,1);
            add_edge(t,s,1);
        }
    }
    for(re int i=1;i<=n;i++)
    {
        memset(f,0,sizeof(f));
        dfs(i,i);
        ans=min(ans,min(f[i][1],f[i][0]));
    }
    cout<<ans;
}

 

posted @ 2018-02-07 15:06  ~victorique~  阅读(182)  评论(0编辑  收藏  举报
Live2D