我们将整个图的所有点分别染成两种颜色,例如绿色和黄色,我们每选一个点,就将它染成绿色,并将所有与它相连的点染成黄色.
在染色过程中,如果发现相邻的两个点是同一种颜色,则说明impossible.
如果成功染完全图,就看选绿色更优还是黄色更优.
1 #include<cstdio> 2 #include<iostream> 3 4 using namespace std; 5 6 int n,m,fa[10001],v[10001],a,b,h[10001]; 7 bool bj[10001]; 8 long long ans; 9 10 inline int find_father(int x) { 11 if(fa[x] == x) return fa[x]; 12 else return fa[x] = find_father(fa[x]); 13 } 14 15 inline void merge(int x,int y) { 16 int x1 = find_father(x); 17 if(x1 != y) { 18 fa[y] = x1; 19 v[x1] += v[y]; 20 } 21 } 22 23 int main() 24 { 25 scanf("%d%d",&n,&m); 26 for(int i = 1;i <= n; i++) { 27 fa[i] = i; 28 v[i] = 1; 29 } 30 for(int i = 1;i <= m; i++) { 31 scanf("%d%d",&a,&b); 32 int f1 = find_father(a); 33 int f2 = find_father(b); 34 if(f1 != f2) { 35 if(h[a]) merge(h[a],f2); 36 if(h[b]) merge(h[b],f1); 37 h[a] = f2; 38 h[b] = f1; 39 } 40 else { 41 printf("Impossible"); 42 return 0; 43 } 44 } 45 for(int i = 1;i <= n; i++) { 46 int q = find_father(i); 47 if(!bj[q]) { 48 int u = find_father(h[i]); 49 ans += min(v[u],v[q]); 50 bj[u] = 1; 51 bj[q] = 1; 52 } 53 } 54 printf("%lld",ans); 55 return 0; 56 }
原文:https://www.cnblogs.com/lipeiyi520/p/11300272.html