圖的遍歷(深搜二分染色判斷奇環與連通 ) 歡樂賽2D
阿新 • • 發佈:2021-07-11
連結:https://ac.nowcoder.com/acm/contest/16806/D
來源:牛客網
無向圖有n個點,從點1開始遍歷,但是規定:按照每次“走兩步”的方式來遍歷整個圖。可以發現按照每次走兩步的方法,不一定能夠遍歷整個圖,所以現在小sun想問你,最少加幾條邊,可以完整的遍歷整個圖。
1. 首先我們可以想到 首先得保證圖的連通性,有n個連通塊需要n-1條邊
2. 然後 需要讓(假設從1開始)其可以走到2(偶數點) 我們需要加一條邊
3 但當圖中出現奇環的時候 便可以直接走到偶數點了 所以若任一連通塊中有奇數環 則直接可以實現
判斷奇數環的方法為二分染色 如圖 深搜時隔點染色 若最後出現連線同色的情況 則有奇環
include<bits/stdc++.h> using namespace std; int n,m; vector<int> g[100005];//存圖 int vis[100005];//標記是否染色,一開始為-1 int flag=1; void dfs(int x) { for(int i=0;i<g[x].size();i++) { int temp=g[x][i]; if(vis[temp]==-1) { vis[temp]=vis[x]^1;//沒染色則染成相反的 dfs(temp);//繼續深搜 } else if(vis[temp]==vis[x])//如果發現不是二分圖說明存在奇圈 { flag=0; } } } int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>n>>m; int x,y; for(int i=0;i<m;i++) { cin>>x>>y; g[x].push_back(y); g[y].push_back(x); } memset(vis,-1,sizeof(vis)); int ans=0; for(int i=1;i<=n;i++) { if(vis[i]==-1) { ++ans;//求連通數 vis[i]=0;//染色 dfs(i); } } cout<<ans-1+flag<<endl; }