Easy to read: for two points \ (u,v \), only one point can block this edge.

What do you mean? If the points on this graph are colored, then for the above two points \ (u,v \), \ (u,v \) must be different colors (it is important to understand this point).

So, that is to say, in this picture, if we want to "completely block" this picture and two river crabs can't block the two adjacent points, in other words, dye the two points connecting one edge, the two points are of different colors, then the whole picture is nothing more than these two colors, and the answer is nothing more than the number of the less of these two colors.

Notice that there is no solution, so when is there no solution? If you think about traversing this picture, you will surely encounter some points you have done. If we think of ourselves as river crabs, then repeatedly arriving at this time is equivalent to re staining this point. If we carry the same "paint" as the last crab, it's equivalent to doing nothing; but if it's different, it's equivalent to re blocking this point, which creates a conflict. Therefore, it is illegal to return 0. Otherwise, return 1.

Please note: this graph may not be connected, so we need to set the vis array to judge whether a point has been used, to traverse all the small connected graphs.

Reference code:

#include <iostream> #include <cstdio> #include <cmath> using namespace std; int n,m,vis[4000010],c[3],head[4000010],tot,_color[4000010]; //_color[u] represents the color of the U-Th point //c [] record the number of two colors struct node { int to,nxt; }; node G[400010]; inline int read() { int s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar(); return s*w; } inline void add(int u,int v) { G[++tot]=(node){v,head[u]},head[u]=tot; G[++tot]=(node){u,head[v]},head[v]=tot; } int dfs(int u,int cor) { if(vis[u]) { if(_color[u]==cor)return 1; return 0; } vis[u]=1; c[_color[u]=cor]++; int can_do=1; for(int i=head[u];i&&can_do;i=G[i].nxt)can_do=can_do&&dfs(G[i].to,1-cor); return can_do; } int main() { int ans; n=read(),m=read(); for(int i=1;i<=m;i++){int u=read(),v=read();add(u,v);} for(int i=1;i<=n;i++) { if(vis[i])continue; c[0]=c[1]=0; if(dfs(i,0)==0){cout<<"Impossible"<<endl;return 0;} ans+=min(c[0],c[1]); //Note, here is the addition } cout<<ans<<endl; return 0; }