CF2204D Alternating Path
思路
题目要求对无向图进行二分图染色,仅合法二分图连通分量计入贡献(取该分量两颜色集合的较大点数),非二分图分量无贡献。核心思路分为三步:
- 通过 BFS 遍历图中所有未访问节点,拆分出每个连通分量。
- 对每个连通分量进行染色,若染色过程中发现相邻节点颜色相同,则判定为非二分图,返回 $-1$;若染色合法,统计两个颜色集合的点数,返回较大值。
- 遍历所有连通分量,将合法二分图分量的最大颜色集合点数累加,得到最终答案。
简单模拟题,但是赛时太卡,一发提交至少等 20min,然后我数组初始化出问题调了三发,幸好 CF 官方延长了时限 15min,不然就没调出来。
世界名画:

极限,尽力了。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| #include<bits/stdc++.h> #define fir first #define sec second #define int long long #define pii pair<int,int> #define fep(i,s,e) for(int i=s;i<e;i++) #define pef(i,s,e) for(int i=s;i>e;i--) #define rep(i,s,e) for(int i=s;i<=e;i++) #define per(i,s,e) for(int i=s;i>=e;i--) namespace FastIO{ template<typename T>inline void read(T &x){ x=0;int f=1;char c=getchar(); for(;!isdigit(c);c=getchar())if(c=='-')f=-1; for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);x*=f; } template<typename T,typename...Args> inline void read(T &x,Args&...args){ read(x); read(args...); } template<typename T>void print(T x){ if(x<0)x=-x,putchar('-'); if(x>9)print(x/10); putchar((x%10)^48); } } using namespace std; using namespace FastIO; const int N=2e5+47; vector<int>G[N]; int c[N]; int T,n,m; void gc(int s,vector<int>&p,int v[]){ queue<int>q; q.push(s); v[s]=1; p.push_back(s); while(!q.empty()){ int u=q.front(); q.pop(); for(int x:G[u]){ if(!v[x]){ v[x]=1; q.push(x); p.push_back(x); } } } }
int chk(const vector<int>&p){ queue<int>q; for(int u:p)c[u]=-1; int u0=p[0]; c[u0]=0; q.push(u0); int cnt[2]={1,0}; int ok=1; while(!q.empty()&&ok){ int u=q.front(); q.pop(); for(int x:G[u]){ if(c[x]==-1){ c[x]=c[u]^1; cnt[c[x]]++; q.push(x); } else if(c[x]==c[u]){ ok=0; break; } } } if(!ok)return -1; return max(cnt[0],cnt[1]); } signed main(){ read(T); while(T--){ read(n,m); rep(i,1,n){ G[i].clear(); c[i]=-1; } fep(i,0,m){ int u,v; read(u,v); G[u].push_back(v); G[v].push_back(u); } int ans=0; int v[N]={0}; rep(u,1,n){ if(!v[u]){ vector<int>p; gc(u,p,v); int res=chk(p); if(res!=-1)ans+=res; } } print(ans); puts(""); } }
|