码迷,mamicode.com
首页 > 其他好文 > 详细

FZU 2112 Tickets

时间:2016-03-11 13:52:10      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:

这个问题可以转变一下,先要知道有几个连通块,连通块之间肯定需要添加一条边,

还需要知道每个连通块内部需要添加几条边,这个问题等价于求一张图至少需要几笔画成,这个问题的答案是度为奇数的点的个数/2

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn=100000+10;
int T;
int n,m;
vector<int>G[maxn];
int tot[maxn];
bool flag[maxn];
bool flag2[maxn];
int q[maxn],sum;
int ans;

void init()
{
    ans=0;
    memset(tot,0,sizeof tot);
    memset(flag,0,sizeof flag);
    memset(flag2,0,sizeof flag2);
}

void read()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) G[i].clear();
    for(int i=1;i<=m;i++)
    {
        int u,v; scanf("%d%d",&u,&v);
        tot[u]++;tot[v]++;
        flag2[u]=1;flag2[v]=1;
        G[u].push_back(v);
        G[v].push_back(u);
    }
}

void dfs(int now)
{
    flag[now]=1; q[sum++]=now;
    for(int i=0;i<G[now].size();i++)
        if(!flag[G[now][i]])
            dfs(G[now][i]);
}

void work()
{
    for(int i=1;i<=n;i++)
    {
        if(!flag[i]&&flag2[i])
        {
            sum=0; ans++; dfs(i);
            int tmp=0;
            for(int j=0;j<sum;j++) if(tot[q[j]]%2==1) tmp++;
            ans=ans+(tmp-1)/2;
        }
    }
    ans--;
    printf("%d\n",ans);
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        init();
        read();
        work();
    }
    return 0;
}

 

FZU 2112 Tickets

标签:

原文地址:http://www.cnblogs.com/zufezzt/p/5265235.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!