uva 10859 Placing Lampposts 树形dp

来源:互联网 发布:日期计算器软件 编辑:程序博客网 时间:2024/05/21 17:19

点击打开链接

图可能不连通,有多棵树。

#include<iostream>#include<string>#include<cstring>#include<cstdio>#include<cmath>#include<iomanip>#include<map>#include<algorithm>#include<queue>#include<set>#define inf 10000000#define pi acos(-1.0)#define eps 1e-8#define seed 131using namespace std;typedef pair<int,int> pii;typedef unsigned long long ULL;typedef long long LL;const int maxn=100005;int n,m;vector<int>vec[1005];int head[1005];int next[1005];int dp[1005][2];int mx[1005][2];bool vis[1005];int p[1005];void dfs(int rt,int fa){    int len=vec[rt].size();    for(int i=0;i<len;i++)    {        if(vec[rt][i]!=fa)        {            next[vec[rt][i]]=head[rt];            head[rt]=vec[rt][i];            dfs(vec[rt][i],rt);        }    }}int DP(int u,int c){    if(dp[u][c]!=-1)        return dp[u][c];    if(c==0)    {        dp[u][0]=0;        mx[u][0]=0;        for(int i=head[u];i!=-1;i=next[i])        {            dp[u][0]+=DP(i,1);            mx[u][0]+=mx[i][1];        }    }    else    {        dp[u][1]=1;        mx[u][1]=0;        for(int i=head[u];i!=-1;i=next[i])        {            //dp[u][1]+=min(DP(i,0),DP(i,1));            int a=DP(i,0);            int b=DP(i,1);            if(a<b)            {                dp[u][1]+=a;                mx[u][1]+=mx[i][0];            }            else if(a==b)            {                dp[u][1]+=a;                mx[u][1]+=max(mx[i][0],mx[i][1]+1);            }            else            {                dp[u][1]+=b;                mx[u][1]+=mx[i][1]+1;            }        }    }    return dp[u][c];}int find(int x){    return p[x]==x?x:p[x]=find(p[x]);}bool un(int i,int j){    int x=find(i);    int y=find(j);    if(x==y)        return false;    p[x]=y;    return true;}int main(){    int t;    scanf("%d",&t);    int a,b;    while(t--)    {        scanf("%d%d",&n,&m);        for(int i=0;i<n;i++)        {            vec[i].clear();            p[i]=i;        }        for(int i=0;i<m;i++)        {            scanf("%d%d",&a,&b);            vec[a].push_back(b);            vec[b].push_back(a);            un(a,b);        }        memset(vis,0,sizeof(vis));        int tot=0,op=0;        for(int i=0;i<n;i++)        {            int q=find(i);            if(vis[q]==0)            {                vis[q]=1;                memset(head,-1,sizeof(head));                dfs(q,-1);                memset(dp,-1,sizeof(dp));                memset(mx,-1,sizeof(mx));                int s1=DP(q,0);                int s2=DP(q,1);                if(s1<s2)                {                    tot+=s1;                    op+=mx[q][0];                }                else if(s1==s2)                {                    tot+=s1;                    op+=max(mx[q][0],mx[q][1]);                }                else                {                    tot+=s2;                    op+=mx[q][1];                }            }        }        printf("%d %d %d\n",tot,op,m-op);    }    return 0;}


0 0