bzoj 1907 树的路径覆盖 [贪心] [树的最小路径覆盖]

来源:互联网 发布:source code pro mac 编辑:程序博客网 时间:2024/05/18 03:38

这里写图片描述


这道题贪心DP都可以做,但是贪心的正确性容易证明,因为子树合并一定不会劣与合并,那么我就贪心了。

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<set>#include<string>#include<iomanip>#include<ctime>#include<climits>#include<cctype>#include<algorithm>#ifdef WIN32#define AUTO "%I64d"#else#define AUTO "%lld"#endifusing namespace std;#define smax(x,tmp) x=max((x),(tmp))#define smin(x,tmp) x=min((x),(tmp))#define maxx(x1,x2,x3) max(max(x1,x2),x3)#define minn(x1,x2,x3) min(min(x1,x2),x3)const int INF=0x3f3f3f3f;const int maxn = 10005;struct Edge{    int to,next;}edge[maxn<<1];int head[maxn];int maxedge;inline void addedge(int u,int v){    edge[++maxedge] = (Edge) { v,head[u] };    head[u] = maxedge;    edge[++maxedge] = (Edge) { u,head[v] };    head[v] = maxedge;}int n;inline void init(){    scanf("%d",&n);    memset(head,-1,sizeof(head));    maxedge=-1;    for(int i=1;i<n;i++)    {        int u,v;        scanf("%d%d",&u,&v);        addedge(u,v);    }}int f[maxn];bool flag[maxn];void dfs(int u,int father){    int cnt=0;    f[u]=1;    for(int i=head[u];~i;i=edge[i].next)    {        int v=edge[i].to;        if(v==father) continue;        dfs(v,u);        f[u]+=f[v];        if(!flag[v]) cnt++;    }    if(cnt>=2) f[u]-=2,flag[u]=true;    else if(cnt==1) f[u]-=1;}int main(){#ifndef ONLINE_JUDGE    freopen("road.in","r",stdin);    freopen("road.out","w",stdout);#endif    int cas;    scanf("%d",&cas);    while(cas--)    {        init();        memset(flag,0,sizeof(flag));        dfs((n+1)>>1,-1);        printf("%d\n",f[(n+1)>>1]);    }    return 0;}
0 0
原创粉丝点击