hdu5438 dfs+并查集 长春网赛

先dfs对度小于2的删边,知道不能删为止。

然后通过并查集来计算每一个分量里面几个元素。

#include<iostream>
#include<cstring>
#include<vector>
#define maxn 10010
#define LL __int64
using namespace std;
int in[maxn],vis[maxn],p,pa[maxn],cou[maxn];
LL sum[maxn];
vector<int>mp[maxn];
void dfs(int u)
{
    int i;
    vis[u]=1;
    for(i=0;i<mp[u].size();i++)
    {
        in[u]--;
        in[mp[u][i]]--;
        if(!vis[mp[u][i]]&&in[mp[u][i]]<2)
            dfs(mp[u][i]);
    }
}
int Find(int x)
{
    if(x!=pa[x])
        pa[x]=Find(pa[x]);
    return pa[x];
}
int main()
{
    int i,j,t,q;
    cin>>t;
    while(t--)
    {
        cin>>p>>q;
        for(i=0;i<=p;i++)
        {
            mp[i].clear();
            pa[i]=i;
            cou[i]=1;
            vis[i]=0;
            in[i]=0;
        }
        for(i=1;i<=p;i++)
        {
            cin>>sum[i];
        }
        while(q--)
        {
            int x,y;
            cin>>x>>y;
            mp[x].push_back(y);
            mp[y].push_back(x);
            in[x]++;
            in[y]++;
        }
        int flag;
        while(1)
        {
            flag=0;
            for(i=1;i<=p;i++)
            {
                if(!vis[i]&&in[i]<2)
                {
                    flag=1;
                    break;
                }
            }
            if(flag==0)
                break;
            for(i=1;i<=p;i++)
            {
                if(!vis[i]&&in[i]<2)
                {
                    dfs(i);
                }
            }
        }
        /*for(i=1;i<=p;i++)
        {
            printf("%d ",in[i]);
        }
        printf("\n");
        for(i=0;i<mp[1].size();i++)
        {
            printf("%d ",mp[1][i]);
        }
        printf("\n");*/
        for(i=1;i<=p;i++)
        {
            if(vis[i])continue;
            int fx=Find(i);
            int num=mp[i].size();
            //printf("%d ",fx);
            for(j=0;j<num;j++)
            {
                if(!vis[mp[i][j]]&&in[mp[i][j]]>=2)
                {
                    int fy=Find(mp[i][j]);
                    if(fx==fy)continue;
                    //printf("%d ",mp[i][j]);
                    pa[fy]=fx;
                    sum[fx]+=sum[fy];
                    cou[fx]+=cou[fy];
                    //printf("%d ",cou[fx]);
                }
            }
            //printf("\n");
        }
        LL ans=0;
        for(i=1;i<=p;i++)
        {
            if(pa[i]==i&&!vis[i]&&cou[i]%2&&cou[i]!=1)
            {
                //printf("%I64d ",sum[i]);
                ans+=sum[i];
            }
        }
        //puts("");
        printf("%I64d\n",ans);
    }
}
/*
9 9
1 2 3 4 5 6 7 8 9
1 2
2 3
3 4
1 4
2 5
5 6
7 8
8 9
7 9
*/

 

posted @ 2015-09-14 22:59  sweat123  阅读(150)  评论(0编辑  收藏  举报