n 隻蟲子,m 對異性交互記錄。判斷記錄中是否存在矛盾(同性交互)。多測試用例。
fa[x] 並查集父節點。opp[x]:與 x 異性的某個蟲子(代表元)。(a,b):
a,b 都無標記:opp[a]=b, opp[b]=a。a 有標記 opp[a]:b 與 opp[a] 同性 → union(b, opp[a])。b 有標記 opp[b]:a 與 opp[b] 同性 → union(a, opp[b])。union(opp[a], b) 且 union(opp[b], a)。find(a)==find(b) → 矛盾。#include <cstdio>
#include <iostream>
using namespace std;
int opp[2005], fa[2005];
int find(int x) { return fa[x]==x?x:fa[x]=find(fa[x]); }
void unite(int a,int b) { int x=find(a),y=find(b); if(x!=y) fa[x]=y; }
int main() {
int T; cin>>T;
for(int tc=1; tc<=T; tc++) {
bool sus=false; int n,m; cin>>n>>m;
for(int i=1;i<=n;i++) fa[i]=i, opp[i]=0;
while(m--) {
int a,b; cin>>a>>b;
if(!opp[a] && !opp[b]) { opp[a]=b; opp[b]=a; }
else if(!opp[a] && opp[b]) { opp[a]=b; unite(a, opp[b]); }
else if(opp[a] && !opp[b]) { opp[b]=a; unite(b, opp[a]); }
else { unite(opp[a], b); unite(opp[b], a); }
if(find(a)==find(b)) sus=true;
}
printf("Scenario #%d:\n", tc);
puts(sus ? "Suspicious bugs found!" : "No suspicious bugs found!");
puts("");
}
return 0;
}
判斷圖是否為二分圖。並查集維護「同性」等價類,opp 記錄異性代表。經典技巧。