HDU2242 考研路茫茫——空调教室(tarjan+树形DP)

http://acm.hdu.edu.cn/showproblem.php?pid=2242

很好的题目

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#define inf (1<<30)
#define nMAX 10005
#define mMAX 20010
using namespace std;
int dfn[nMAX],low[nMAX],belon[nMAX],sta[nMAX],top,times,atype;
int s_edge,s_edge2,head[nMAX],head2[nMAX];
int n,num1[nMAX],num2[nMAX],SUM,ans;
struct Edge
{
    int v,nxt;
}edge[2*mMAX],edge2[2*mMAX];
void addedge(int u,int v)
{
    s_edge++;
    edge[s_edge].v=v;
    edge[s_edge].nxt=head[u];
    head[u]=s_edge;
}
void addedge2(int u,int v)
{
    s_edge2++;
    edge2[s_edge2].v=v;
    edge2[s_edge2].nxt=head2[u];
    head2[u]=s_edge2;
}
void tarjan(int u,int fa)
{
    int fg=0;
    dfn[u]=low[u]=++times;
    sta[++top]=u;
    for(int e=head[u];e;e=edge[e].nxt)
    {
        int v=edge[e].v;
        if(!fg&&v==fa) {fg=1;continue;}
        if(!dfn[v])
        {
            tarjan(v,u);
            low[u]=min(low[u],low[v]);  
        }
        else low[u]=min(low[u],dfn[v]);

    }
    int j;
    if(dfn[u]==low[u])
    {
        atype++;
        do{
            j=sta[top--];
            belon[j]=atype;
            num2[atype]+=num1[j];
        }while(j!=u);
    }
}
int dfs(int u,int pre)
{
    int sum=num2[u];
    for(int e=head2[u];e;e=edge2[e].nxt)
    {
        int v=edge2[e].v;
        if(v==pre) continue;
        sum+=dfs(v,u);
    }
    int t=abs(SUM-2*sum);
    ans=min(ans,t);
    return sum;
}
void init()
{
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(num2,0,sizeof(num2));
    top=0;
    times=0;
    atype=0;
}
int main()
{
    int i,j,m;
    while(~scanf("%d%d",&n,&m))
    {
        SUM=0;
        for(i=0;i<n;i++) {scanf("%d",&num1[i]);SUM+=num1[i];}
        memset(head,0,sizeof(head));
        s_edge=0;
        while(m--)
        {
            scanf("%d%d",&i,&j);
            addedge(i,j);
            addedge(j,i);
        }
        init();
        tarjan(0,-1);
        if(atype==1){printf("impossible\n");continue;}
        memset(head2,0,sizeof(head2));
        s_edge2=0;
        for(i=0;i<n;i++)
        {
            for(int e=head[i];e;e=edge[e].nxt)
            {
                int v=edge[e].v;
                if(belon[i]!=belon[v]) addedge2(belon[i],belon[v]);
            }
        }
        ans=inf;
        dfs(1,0);
        printf("%d\n",ans);
    }
    return 0;
}

  

  

posted @ 2012-10-17 23:47  快乐.  阅读(149)  评论(0编辑  收藏  举报