呜呜来晚了。。。

题目大意:

你只能两步两步的走,问你最少添加多少条边才可以使得你能遍历完整个图

题解:

我们每次只能两步两步地走,那么如果,我们走一条边再回去,这是毫无意义的。

如果,我们一个图中没有无向边环,(也即是图的形状类似于树),那么,很明显的,一个点到另外一个点走的步数的奇偶性就确定了,而且,必然无法走通,我们就必须考虑添边。

那么要添几条边呢?

我们分析下,我们现在添加一条边后,就必然产生了一个无向边环,那么我们讨论下这个环的奇偶性即可。

如果这个环是偶环,那么,我们走一遍环后,步数奇偶性不变,原来不能到达的点现在还是不能到达,没用。

如果这个环是奇环,那么,我们走一遍环后,步数奇偶性就改变了,原来不能到达的点都可以到达了。

于是,我们只需要添一条边构造出一个奇环就行了。

如果原本就存在奇环的话,就不需要添加奇环了

但是,我们的图并不能保证连通啊,这个怎么办呢?

很简单,我们先添几条边,把图做连通后,再判断图中是否存在奇环即可

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1;
struct node{
    int v,nex;
}t[N<<1];
bool col[N];
int len,las[N];bool vis[N],flag=1;//是否没有奇环
inline void add(int u,int v){
    t[++len]=(node){v,las[u]},las[u]=len;
}
inline void dfs(int now){
    vis[now]=1;
    for(int i=las[now];i;i=t[i].nex){
        int v=t[i].v;
        if(vis[v]){
            if(col[v]==col[now])flag=0;
            continue;
        }
        col[v]=(col[now]^1);
        dfs(v);
    }
    return;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v),add(v,u);
    }
    int ans=0;
    dfs(1);
    for(int i=2;i<=n;++i){
        if(!vis[i]){
            ++ans,dfs(i);//添加若干条边使得图连通
        }
    }
    printf("%d",ans+flag);
    return 0;
}