1156. Two Rounds
Time limit: 2.0 second
Memory limit: 64 MB
Memory limit: 64 MB
There are two rounds in the Urals Championship. The competitors have to solve
N problems on each round. The jury had been working hard and finally managed to prepare 2
N problems for the championship. But it appeared that among those problems there were some, which have the analogous solutions. One shouldn’t assign such a problems for the same round. Please, help the jury form sets of tasks for each of the rounds.
Input
First line contains two numbers:
N, the number of tasks for a round, and
M, the number of pairs of tasks which should not be assigned for one round (1 ≤
N ≤ 50; 0 ≤
M ≤ 100). Then
M lines follow, each of them contains two numbers of analogous tasks.
Output
Output two lines, containing numbers of tasks assigned for each round. If there is no solution, output the only word “IMPOSSIBLE”. If there are more than one solution you may assume anyone of them.
Sample
input | output |
---|---|
2 3 1 3 2 1 4 3 | 1 4 2 3 |
Problem Author: Eugene Bryzgalov
Problem Source: Ural Collegiate Programming Contest, April 2001, Perm, English Round
Problem Source: Ural Collegiate Programming Contest, April 2001, Perm, English Round
Difficulty: 342
题意:给出n,代表有2*n个点,给出m对关系,每队表示a,b不能分一组。问将2*n个点 平均 分成两组的方案。
分析:首先判断无解情况是很显然的,将点连边,奇偶分层后就行了
一堆相互联系的点(即有边相连或间接相连的点)分开的情况是确定的,比如奇数层的点数a,偶数层的点数b,a,b是确定的,只是a,b哪个去哪个组未确定。
因为每组都要n个点,所以只能背包了。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <iostream> 9 #include <algorithm> 10 #include <map> 11 #include <set> 12 #include <ctime> 13 using namespace std; 14 typedef long long LL; 15 typedef double DB; 16 #define For(i, s, t) for(int i = (s); i <= (t); i++) 17 #define Ford(i, s, t) for(int i = (s); i >= (t); i--) 18 #define Rep(i, t) for(int i = (0); i < (t); i++) 19 #define Repn(i, t) for(int i = ((t)-1); i >= (0); i--) 20 #define rep(i, x, t) for(int i = (x); i < (t); i++) 21 #define MIT (2147483647) 22 #define INF (1000000001) 23 #define MLL (1000000000000000001LL) 24 #define sz(x) ((int) (x).size()) 25 #define clr(x, y) memset(x, y, sizeof(x)) 26 #define puf push_front 27 #define pub push_back 28 #define pof pop_front 29 #define pob pop_back 30 #define ft first 31 #define sd second 32 #define mk make_pair 33 inline void SetIO(string Name) { 34 string Input = Name+".in", 35 Output = Name+".out"; 36 freopen(Input.c_str(), "r", stdin), 37 freopen(Output.c_str(), "w", stdout); 38 } 39 40 inline int Getint() { 41 int Ret = 0; 42 char Ch = ' '; 43 while(!(Ch >= '0' && Ch <= '9')) Ch = getchar(); 44 while(Ch >= '0' && Ch <= '9') { 45 Ret = Ret*10+Ch-'0'; 46 Ch = getchar(); 47 } 48 return Ret; 49 } 50 51 const int N = 110; 52 int n, m; 53 bool Map[N][N]; 54 int Color[N], Pair[N][2], Len, Who[N]; 55 bool Dp[N][N][N], Flag, Visit[N]; 56 int Ans[N]; 57 vector<int> Day[2]; 58 59 inline void Input() { 60 scanf("%d%d", &n, &m); 61 For(i, 1, m) { 62 int a, b; 63 scanf("%d%d", &a, &b); 64 Map[a][b] = Map[b][a] = 1; 65 } 66 } 67 68 inline void Search(int x, int C) { 69 if(Flag) return; 70 Color[x] = C, Pair[Len][C-1]++; 71 int _C = ((C-1)^1)+1; 72 For(i, 1, n*2) 73 if(Map[x][i]) { 74 if(Color[i] && Color[i] != _C) { 75 Flag = 1; 76 break; 77 } 78 79 if(!Color[i]) Search(i, _C); 80 } 81 } 82 83 inline void Solve() { 84 For(i, 1, n*2) 85 if(!Color[i]) { 86 Who[++Len] = i; 87 Search(i, 1); 88 if(Flag) break; 89 } 90 91 if(Flag) { 92 puts("IMPOSSIBLE"); 93 return; 94 } 95 96 Dp[0][0][0] = 1; 97 For(i, 1, Len) { 98 int a = Pair[i][0], b = Pair[i][1]; 99 For(j, 0, n) 100 For(k, 0, n) { 101 if(j+a <= n && k+b <= n) 102 Dp[i][j+a][k+b] |= Dp[i-1][j][k]; 103 if(j+b <= n && k+a <= n) 104 Dp[i][j+b][k+a] |= Dp[i-1][j][k]; 105 } 106 } 107 108 if(!Dp[Len][n][n]) { 109 puts("IMPOSSIBLE"); 110 return; 111 } 112 113 int a = n, b = n; 114 Ford(i, Len, 1) { 115 if(a >= Pair[i][0] && b >= Pair[i][1] && Dp[i-1][a-Pair[i][0]][b-Pair[i][1]]) { 116 Ans[Who[i]] = 1, Visit[i] = 1; 117 a -= Pair[i][0], b -= Pair[i][1]; 118 } else if(a >= Pair[i][1] && b >= Pair[i][0] && Dp[i-1][a-Pair[i][1]][b-Pair[i][0]]) { 119 Ans[Who[i]] = 2, Visit[i] = 1; 120 a -= Pair[i][1], b -= Pair[i][0]; 121 } 122 } 123 124 clr(Color, 0); 125 For(i, 1, n*2) 126 if(Ans[i]) Search(i, Ans[i]); 127 128 For(i, 1, n*2) 129 Day[Color[i]-1].pub(i); 130 Rep(i, 2) { 131 int Length = sz(Day[i]); 132 Rep(j, Length-1) printf("%d ", Day[i][j]); 133 printf("%d\n", Day[i].back()); 134 } 135 } 136 137 int main() { 138 #ifndef ONLINE_JUDGE 139 SetIO("G"); 140 #endif 141 Input(); 142 Solve(); 143 return 0; 144 }