zoukankan      html  css  js  c++  java
  • hdu 2242双联通分量+树形dp

    /*先求出双联通缩点,然后进行树形dp*/
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #define inf 0x3fffffff
    #define N  11000
    struct node
    {
        int u,v,next;
    } bian[N*4],edge[N*4];
    int head[N],yong,dfn[N],low[N],index,f[N*4],cnt,n,num[N];
    int yon;
    int belong[N],tot[N];
    int visit[N],dp[N];
    void init()
    {
        memset(head,-1,sizeof(head));
        yong=0;
        index=0;
        cnt=0;
        memset(dfn,0,sizeof(dfn));
        memset(f,0,sizeof(f));
        memset(low,0,sizeof(low));
    }
    int Min(int a,int b)
    {
        return a>b?b:a;
    }
    void addedge(int u,int v)  //一次建图
    {
        bian[yong].u=u;
        bian[yong].v=v;
        bian[yong].next=head[u];
        head[u]=yong++;
    }
    void tarjan(int u,int pre ) //tarjan算法求桥
    {
        dfn[u]=low[u]=++index;
        int i;
        for(i=head[u]; i!=-1; i=bian[i].next)
        {
            int v=bian[i].v;
            if(i==(pre^1))continue;
            if(!dfn[v])
            {
                tarjan(v,i);
                low[u]=Min(low[u],low[v]);
                if(low[v]>dfn[u])
                {
                    cnt=1;//是否存在桥
                    f[i]=f[i^1]=1;//标记桥
                }
            }
            else
                low[u]=Min(low[u],dfn[v]);
        }
        return ;
    }
    void dfs(int u,int pre)
    {
        belong[u]=cnt;//缩
        tot[cnt]+=num[u];//记录缩点的权值
        int i,v;
        for(i=head[u]; i!=-1; i=bian[i].next)
        {
            v=bian[i].v;
            if(!f[i]&&!belong[v]&&i!=(pre^1))
                dfs(v,i);
        }
        return ;
    }
    void addedge1(int u,int v)  //二次建图
    {
        edge[yon].u=u;
        edge[yon].v=v;
        edge[yon].next=head[u];
        head[u]=yon++;
    }
    void slove()
    {
        int i;
        memset(belong,0,sizeof(belong));
        memset(tot,0,sizeof(tot));
        cnt=0;
        for(i=1; i<=n; i++)
            if(!belong[i])  //缩点
            {
                cnt++;
                dfs(i,-1);
            }
        memset(head,-1,sizeof(head));
        yon=0;
        for(i=0; i<yong; i++) //重新建图
        {
            int u=bian[i].u,v=bian[i].v;
            if(belong[u]!=belong[v])
            {
                addedge1(belong[u],belong[v]);
                addedge1(belong[v],belong[u]);
                //      printf("%d %d
    ",belong[u],belong[v]);
            }
        }
        return ;
    }
    
    int dfs1(int u)  //为树形图求出他和他的子节点的权值
    {
        visit[u]=1;
        int i,v,sum=0;
        sum+=tot[u];
        for(i=head[u]; i!=-1; i=edge[i].next)
        {
            v=edge[i].v;
            if(!visit[v])
            {
                sum+=dfs1(v);
            }
        }
    //printf("%d %d
    ",u,sum);
        dp[u]=sum;
        return sum;
    }
    int main()
    {
        int m,i,j,k,a,b,c,sum,minn;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            sum=0;
            init();
            for(i=1; i<=n; i++)
            {
                scanf("%d",&num[i]);
                sum+=num[i];
            }
            while(m--)
            {
                scanf("%d%d",&a,&b);
                a++;
                b++;
                addedge(a,b);
                addedge(b,a);
            }
            tarjan(1,-1);
            if(cnt==0)  //如果不存在桥
            {
                printf("impossible
    ");
                continue;
            }
            slove();
            memset(visit,0,sizeof(visit));
            dfs1(1);
            minn=inf;
            for(i=1; i<=cnt; i++)
            {
                // printf("%d
    ",dp[i]);
                minn=Min(minn,fabs(sum*1.0-2.0*dp[i]));//求最优
            }
            printf("%d
    ",minn);
        }
        return 0;
    }
    

  • 相关阅读:
    用Java实现四则运算
    敏捷开发角色分配
    需求分析之WBS
    需求分析之NABCD
    电梯演说
    开发流程的选择
    软件团队模式的选择
    维护日程管理项目
    日程管理系统中找错误
    Android的测试
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410673.html
Copyright © 2011-2022 走看看