1156. Two Rounds(dfs+背包)

1156

求出每个联通块的黑白块数 然后再背包 二维的背包 要保证每个块都得取一个

写的有些乱。。

  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\n");
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 }
View Code

 

posted @ 2013-10-15 12:11  _雨  阅读(402)  评论(0编辑  收藏  举报