题意:给一个图,问能否把每条边的2端放在2个不同的集合里
思路:暴搜01染色,以颜色做为标记每次搜索的时候可以遍历到一个联通块里的所有边,但是注意在搜索的时候如果发现下一个点已经被染色了,那么在退出这层搜索前需要判断一下下一个点的颜色是否和当前点的颜色一样
AC代码:
#include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #pragma comment(linker, "/STACK:102400000,102400000") #define ll long long #define bug(x) cout<<x<<" "<<"UUUUU"<<endl; #define mem(a,x) memset(a,x,sizeof(a)) #define mp(x,y) make_pair(x,y) #define pb(x) push_back(x) #define lrt (rt<<1) #define rrt (rt<<1|1) using namespace std; const long long INF = 1e18+1LL; const int inf = 1e9+1e8; const int N=1e5+100; const ll mod=1e9+7; ///CCCC int cl[N<<1],vis[N<<1],nex[N<<2],head[N<<1],to[N<<1],id[N<<1],tot,flag,ans[3]; void add(int u, int v){ to[tot]=v; nex[tot]=head[u]; head[u]=tot++; } void dfs(int u,int c){ //bug("xx") if(cl[u]==c){ flag=1; return; } cl[u]=c^1; ans[c^1]++; for(int i=head[u]; i!=-1; i=nex[i]){ int v=to[i]; if(cl[v]!=-1){ if(cl[u]==cl[v]){ flag=1; return; } continue; } dfs(v,cl[u]); } } int main(){ int n,m,u,v; cin>>n>>m; mem(head,-1), mem(cl,-1); for(int i=1; i<=m; ++i){ cin>>u>>v; add(u,v); add(v,u); id[u]=1; id[v]=1; } for(int i=1; i<=n; ++i){ //cout<<cl[i]<<" "<<id[i]<<" "; if(cl[i]==-1 && id[i]==1) dfs(i,1); if(flag){ cout<<"-1 "; return 0; } } cout<<ans[0]<<" "; for(int i=1; i<=n; ++i){ if(id[u] && cl[i]==0){ cout<<i<<" "; } } cout<<" "; cout<<ans[1]<<" "; for(int i=1; i<=n; ++i){ if(id[u] && cl[i]==1){ cout<<i<<" "; } } return 0; }