思路:显然是和边双连通分量有关的,所以只需要在双连通分量中找奇环(二分图染色),如果找到,这个连通分量中的点都是满足的。
// #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <limits.h> // #define DEBUG #ifdef DEBUG #define debug(...) printf( __VA_ARGS__ ) #else #define debug(...) #endif #define MEM(x,y) memset(x, y,sizeof x) using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 10010; int dfn[maxn], low[maxn], Belong[maxn], num[maxn]; int Time; int BCC; int n, m; vector<int> G[maxn]; void Init(){ for (int i = 0;i < n;++i) G[i].clear(); Time = BCC = 0; memset(dfn, -1,sizeof dfn); } void Read(){ int u, v; for (int i = 0;i < m;++i){ scanf("%d%d",&u,&v); G[u].push_back(v); G[v].push_back(u); } } stack<int> st; void Tarjan(int u,int fa){ dfn[u] = low[u] = Time++; st.push(u); int cnt = 0; for (int i = 0;i < G[u].size();++i){ int v = G[u][i]; if (v == fa && cnt == 0){ cnt = 1; continue; } if (dfn[v] == -1){ Tarjan(v, u); low[u] = min(low[u], low[v]); }else low[u] = min(low[u], dfn[v]); } if (low[u] == dfn[u]){ BCC++; num[BCC] = 0; while(true){ int v = st.top(); st.pop(); num[BCC]++; Belong[v] = BCC; if (u == v) break; } } } int Color[maxn]; bool vis[maxn]; bool DFS(int u, int ID){ for (int i = 0;i < G[u].size();++i){ int v = G[u][i]; if (Belong[v] != ID) continue; if (Color[u] == Color[v]) return false;//奇环 if (Color[u] + Color[v] == 3) continue;//偶环 if (Color[v] == -1){ Color[v] = 3 - Color[u]; if (!DFS(v, ID)) return false; } } return true; } int icase = 0; void solve(){ for (int i = 0;i < n;++i) if (dfn[i] == -1) Tarjan(i, -1); // printf("BCC = %d\n", BCC); memset(Color, -1,sizeof Color); memset(vis, false,sizeof vis); int sum = 0; for (int i = 0;i < n;++i){ int ID = Belong[i]; if (vis[ID]) continue; vis[ID] = true; Color[i] = 1; if (!DFS(i, ID)) sum += num[ID]; } printf("Case %d: %d\n", ++icase, sum); } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); Init(); Read(); solve(); } return 0; }