求出每个联通块的黑白块数 然后再背包 二维的背包 要保证每个块都得取一个
写的有些乱。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<stdlib.h> 5 #include<algorithm> 6 #include<vector> 7 using namespace std; 8 vector<int>ed[110]; 9 int x,y,flag,g,f[110],o[110],n,q[110]; 10 int co[110],a[110],b[110],dp[110][110]; 11 int vis[110],p[110][110][2]; 12 void dfs(int u,int c) 13 { 14 int i; 15 if(co[u]==1) 16 { 17 x++; 18 p[g][x][0] = u; 19 } 20 else 21 { 22 y++; 23 p[g][y][1] = u; 24 } 25 for(i = 0 ; i < (int)ed[u].size() ; i++) 26 { 27 int v = ed[u][i]; 28 if(co[v]) 29 { 30 if(co[v]!=-c) 31 { 32 flag = 1; 33 return ; 34 } 35 } 36 else 37 { 38 co[v] = -c; 39 dfs(v,-c); 40 } 41 } 42 } 43 void dfs2(int s,int v) 44 { 45 if(flag) return ; 46 int i; 47 if(s==0) 48 { 49 if(v==0) 50 { 51 flag = 1; 52 return ; 53 } 54 else 55 return ; 56 } 57 for(i = 1; i <= g ;i++) 58 { 59 if(!vis[i]&&s-a[i]>=0&&dp[v-1][s-a[i]]) 60 { 61 f[i] = 1; 62 vis[i] = 1; 63 dfs2(s-a[i],v-1); 64 if(flag) return; 65 f[i] = 0; 66 vis[i] = 0; 67 } 68 if(!vis[i]&&s-b[i]>=0&&dp[v-1][s-b[i]]) 69 { 70 f[i] = 2; 71 vis[i] = 1; 72 dfs2(s-b[i],v-1); 73 if(flag) return ; 74 vis[i] = 0; 75 f[i] = 0; 76 } 77 } 78 } 79 int main() 80 { 81 int m,i,j; 82 scanf("%d%d",&n,&m); 83 for(i = 1; i <= m ; i++) 84 { 85 int u,v; 86 scanf("%d%d",&u,&v); 87 ed[u].push_back(v); 88 ed[v].push_back(u); 89 } 90 for(i = 1; i <= 2*n ; i++) 91 { 92 if(!co[i]) 93 { 94 g++;x=0;y=0; 95 co[i] = 1; 96 dfs(i,1); 97 a[g] = x; 98 b[g] = y; 99 } 100 if(flag) 101 break; 102 } 103 if(flag) 104 { 105 puts("IMPOSSIBLE "); 106 return 0; 107 } 108 else 109 { 110 dp[0][0] = 1; 111 for(i = 1; i <= g ; i++) 112 for(int k = g; k >= 1 ; k--) 113 { 114 for(j = n ; j >= 0 ; j--) 115 { 116 if(j>=a[i]) 117 dp[k][j] = max(dp[k][j],dp[k-1][j-a[i]]); 118 if(j>=b[i]) 119 dp[k][j] = max(dp[k][j],dp[k-1][j-b[i]]); 120 } 121 } 122 if(!dp[g][n]) 123 puts("IMPOSSIBLE"); 124 else 125 { 126 dfs2(n,g); 127 for(i = 1; i <= g ; i++) 128 if(f[i]) 129 { 130 if(f[i]==1) 131 for(j = 1 ; j <= a[i] ; j++) 132 { 133 printf("%d ",p[i][j][0]); 134 q[p[i][j][0]] = 1; 135 } 136 else 137 for(j = 1 ; j <= b[i] ; j++) 138 { 139 printf("%d ",p[i][j][1]); 140 q[p[i][j][1]] = 1; 141 } 142 } 143 puts(""); 144 for(i = 1; i <= 2*n ;i++) 145 if(!q[i]) 146 printf("%d ",i); 147 puts(""); 148 } 149 } 150 return 0; 151 }