题意:有一个n个点节点m条边的无向图,从点1开始遍历,按照每次“走两步”遍历整个图。可以发现按照每次走两步的方法,不一定能够遍历整个图,所以最少加几条边,可以完整的遍历整个图?
思路:如果一个连通块中有奇数环,则该连通块可以全部遍历到,加一条边可以使二个连通块合在一起,最后在一个大于等于3的连通块中加一条边可以创造一个奇数环(如果没有奇数环),所以当有奇数环时答案为连通块的个数-1,否则为连通块的个数。
代码:
#include<bits/stdc++.h> #define ll long long #define inf 1000000007 using namespace std; vector<int>g[100005]; int ma[100005]; int dfs(int v,int k) { ma[v]=k; int flag=0; for(int i=0; i<g[v].size(); i++) { if(ma[g[v][i]]==0) { flag=flag|dfs(g[v][i],k+1); } else { if((ma[v]-ma[g[v][i]])%2==0) { flag=1; } } } return flag; } int main() { int n, m; scanf("%d %d",&n,&m); for(int i=0; i<m; i++) { int s, e; scanf("%d%d",&s,&e); g[s].push_back(e); g[e].push_back(s); } int z=0, flag=0; for(int i=1; i<=n; i++) { if(ma[i]==0) { flag=flag|dfs(i,0); z++; } } z=z-flag; cout << z << endl; return 0; }