1156. Two Rounds

1156. Two Rounds

Time limit: 2.0 second 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 Nproblems 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  
***************************************************************************************
刚开始想到了贪心,觉得和前几天做的一个题相似,但wa了很多次,自己觉得没有漏洞,可能是想的不全面(还得再想)唉唉…………,最后看了题解,都说这题是二维01背包的变形,不过要装的是不排斥的集合,关键找集合(深搜)存在解时背包正好装满,解法的总体结构很难想到!!!!!!!!!!!!!!!!!
***************************************************************************************
  1 #include<iostream>
  2 #include<string>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<vector>
  6 #include<queue>
  7 #include<cstdio>
  8 using namespace std;
  9 int f[1001];//存该元素属于哪组数组(标记数组)
 10 vector<int>hate[1001];//相互排斥的数组
 11 int choose[1001][1001];//存储i组数据的的两个集合并标记
 12 int sel[1001];//链状找出一节点属于哪个集合
 13 int num1[1001],num2[1001];//每组数据中,两个集合的元素数;
 14 int st,en;
 15 int n,m,i,j;
 16 bool dfs(int x,int k)//深搜有几组数据
 17  {
 18      if(f[x]!=0)
 19      {
 20          if(f[x]==k)
 21           return true;
 22          return false;
 23      }
 24      f[x]=k;
 25      if(k>0)
 26        ++num1[k];
 27      else
 28        ++num2[-k];
 29      for(int is=0;is<hate[x].size();is++)
 30       {
 31           if(!dfs(hate[x][is],-k))
 32            return false;
 33       }
 34     return  true;
 35 
 36  }
 37  int main()
 38  {
 39      cin>>n>>m;
 40      for(i=1;i<=m;i++)
 41       {
 42           cin>>st>>en;
 43           hate[st].push_back(en);//存排斥数组
 44           hate[en].push_back(st);
 45       }
 46      memset(f,0,sizeof(f));
 47      memset(num1,0,sizeof(num1));
 48      memset(num2,0,sizeof(num2));
 49      memset(choose,0,sizeof(choose));
 50      int ry=1;
 51      int gs=1;
 52      for(i=1;i<=2*n;i++)
 53       if(f[i]==0)
 54        {
 55            if(!dfs(i,ry))
 56            {
 57                gs=0;
 58                break;
 59            }
 60 
 61            ry++;
 62        }
 63       if(gs==0)
 64        {
 65            cout<<"IMPOSSIBLE"<<endl;
 66            return 0;
 67        }
 68 
 69      m=ry-1;
 70      choose[0][0]=1;
 71      for(i=0;i<m;i++)
 72       {
 73           for(j=0;j<=n;j++)
 74            {
 75                if(choose[i][j]==0)
 76                 continue;
 77                 choose[i+1][j+num1[i+1]]=1;//标记当数量j和j+num1[i+1]时可达,并标明属于该组数据集合中哪个集合。
 78                 choose[i+1][j+num2[i+1]]=-1;//同上
 79             }
 80 
 81       }
 82       if(choose[m][n]==0)
 83        {
 84            cout<<"IMPOSSIBLE"<<endl;
 85            return 0;
 86        }
 87        int k=n;
 88       for(i=m;i>=1;i--)
 89        {
 90            sel[i]=choose[i][k];//链状查找和标记(我认为这样称呼更形象)
 91            if(choose[i][k]>0)
 92             k-=num1[i];
 93            else
 94             k-=num2[i];
 95        }
 96        for(i=1;i<=2*n;i++)//输出
 97         if((f[i]>0&&sel[f[i]]>0)||(f[i]<0&&sel[-f[i]]<0))
 98         cout<<i<<' ';
 99        cout<<endl;
100        for(i=1;i<=2*n;i++)
101         if(!(f[i]>0&&sel[f[i]]>0)&&!(f[i]<0&&sel[-f[i]]<0))
102         cout<<i<<' ';
103         cout<<endl;
104         return 0;
105  }
View Code

持之以恒,方能取胜

转载于:https://www.cnblogs.com/sdau--codeants/p/3257591.html

猜你喜欢

转载自blog.csdn.net/weixin_34301132/article/details/93432967
two