zoukankan      html  css  js  c++  java
  • URAL 1182. Team Them Up!

    1182. Team Them Up!

    Time limit: 1.0 second Memory limit: 64 MB
    Your task is to divide a number of persons into two teams, in such a way, that:
    • everyone belongs to one of the teams;
    • every team has at least one member;
    • every person in the team knows every other person in his team;
    • teams are as close in their sizes as possible.
    This task may have many solutions. You are to find and output any solution, or to report that the solution does not exist.

    Input

    For simplicity, all persons are assigned a unique integer identifier from 1 to N.
    The first line contains a single integer number N (2 ≤ N ≤ 100) - the total number of persons to divide into teams, followed by N lines - one line per person in ascending order of their identifiers. Each line contains the list of distinct numbers Aij (1 ≤ Aij ≤ N, Aij ≠ i) separated by spaces. The list represents identifiers of persons that ith person knows. The list is terminated by 0.

    Output

    If the solution to the problem does not exist, then write a single message “No solution” (without quotes). Otherwise write a solution on two lines. On the first line write the number of persons in the first team, followed by the identifiers of persons in the first team, placing one space before each identifier. On the second line describe the second team in the same way. You may write teams and identifiers of persons in a team in any order.

    Sample

    inputoutput
    5
    2 3 5 0
    1 4 5 3 0
    1 2 5 0
    1 2 3 0
    4 3 2 1 0
    
    3 1 3 5
    2 2 4
    
    Problem Author: Vladimir Kotov, Roman Elizarov  Problem Source: 2001-2002 ACM Northeastern European Regional Programming Contest
    *****************************************************************************************************
    求补图&&dfs算法&&背包问题f[][],,,染色问题,程序中有解释
    *****************************************************************************************************
      1 /*本题主要是要求补图
      2 和dfs求连通块,每个连通块分成两部分x[][],y[][];
      3 然后再用01背包求出最小值并标记
      4 最后输出计算结果,此处注意x[i][0],y[i][0]是表示i个连通块中两部分的数量
      5 v[i]数组用于标记,点i属于哪个组。
      6 */
      7 #include<iostream>
      8 #include<string>
      9 #include<cstring>
     10 #include<cstdio>
     11 #include<cmath>
     12 #include<algorithm>
     13 using namespace std;
     14 const int maxn=110;
     15 int e[1001][1001];
     16 int v[1001],x[1001][1001],y[1001][1001];
     17 int f[1001][1001];
     18 int n,m,j,i,p;
     19 int tmp;
     20 int absw(int x)
     21 {
     22     return (x<0)?(-x):x;
     23 }
     24 void init()
     25 {
     26     cin>>n;
     27     memset(e,0,sizeof(e));
     28     for(i=0;i<n;i++)//建图
     29      {
     30          while(cin>>tmp&&tmp)
     31           {
     32               e[i][tmp-1]=1;
     33           }
     34      }
     35      for(i=0;i<n;i++)//求补图
     36       for(j=0;j<i;j++)
     37        {
     38            if(e[i][j]==1&&e[j][i]==1)
     39             e[i][j]=e[j][i]=0;
     40            else
     41              e[i][j]=e[j][i]=1;
     42        }
     43 }
     44 bool  dfs(int k,int p,int xx)//染色、求连通块
     45        {
     46          for(int it=0;it<n;it++)
     47            if(it!=k&&e[it][k]==1)
     48             {
     49                 if(v[it]==-1)
     50                  {
     51                      if(xx==1)
     52                       y[p][++y[p][0]]=it;
     53                      else
     54                       x[p][++x[p][0]]=it;
     55                      v[it]=xx;
     56                      if(!dfs(it,p,1-xx))return false;
     57                  }
     58                  else
     59                    if(v[k]==v[it])return  false;
     60 
     61             }
     62             return true;
     63      }
     64  bool solve()
     65   {
     66       int ans,g1;
     67       p=0;
     68       memset(v,-1,sizeof(v));
     69       for(i=0;i<n;i++)
     70        {
     71            if(v[i]==-1)
     72             {
     73                v[i]=0;x[p][0]=1;x[p][1]=i;y[p][0]=0;
     74                if(!dfs(i,p,1)) return false;
     75                p++;//p个连通块
     76             }
     77        }
     78        memset(f,255,sizeof(f));
     79        f[0][x[0][0]-y[0][0]+maxn]=0;
     80        f[0][y[0][0]-x[0][0]+maxn]=1;
     81        for(i=1;i<p;i++)//背包问题、f[i][j]表示前i个连通块中当差为j时取x(0)或y(1);
     82         for(j=1;j<=maxn*2;j++)
     83          {
     84              if(f[i-1][j]!=-1)
     85               f[i][j+x[i][0]-y[i][0]]=0;
     86              if(f[i-1][j]!=-1)
     87               f[i][j+y[i][0]-x[i][0]]=1;
     88          }
     89         ans=-1;
     90         for(j=0;j<=maxn*2;j++)
     91          if(f[p-1][j]!=-1)
     92           if(ans==-1||absw(ans-maxn)>absw(j-maxn))
     93             ans=j;//最小差值
     94        g1=0;
     95       for(i=p-1;i>=0;i--)//背包问题从后往前找
     96          if(f[i][ans]==0)
     97           {
     98             g1+=x[i][0];
     99             for(j=1;j<=x[i][0];j++)v[x[i][j]]=1;
    100             for(j=1;j<=y[i][0];j++)v[y[i][j]]=2;
    101             ans-=(x[i][0]-y[i][0]);
    102           }
    103           else
    104            {
    105                g1+=y[i][0];
    106                for(j=1;j<=x[i][0];j++)
    107                 v[x[i][j]]=2;
    108                for(j=1;j<=y[i][0];j++)
    109                 v[y[i][j]]=1;
    110             ans-=(y[i][0]-x[i][0]);
    111            }
    112         //输出计算结果
    113         cout<<g1<<' ';
    114         for(i=0;i<n;i++)
    115           if(v[i]==1)
    116             cout<<i+1<<' ';
    117         cout<<endl;
    118        cout<<n-g1<<' ';
    119        for(i=0;i<n;i++)
    120          if(v[i]==2)
    121            cout<<i+1<<' ';
    122        cout<<endl;
    123       return true;
    124 
    125   }
    126   int main()
    127   {
    128       init();
    129       if(!solve())
    130        cout<<"No solution"<<endl;
    131   }
    View Code

    坚持!!!!!

  • 相关阅读:
    财务报表分析(张新民教授)-第五章 企业报表战略分析(1):资源配置战略(续)
    财务报表分析(张新民教授)-第五章 企业报表战略分析(1):资源配置战略
    财务报表分析(张新民教授)-第四章 企业经营活动与财务报表的关系
    以商品为生25:交易商品价差
    以商品为生22:页岩油与水力压裂的优缺点
    以商品为生17:石油价格历史——自1974年以来的高点和低点
    以商品为生15:商品交易中的Backwardation和Contango
    以商品为生14:大宗商品投资者的大豆交易指南
    以商品为生11:来自USDA的月度WASDE报告
    AJAX 跨域请求
  • 原文地址:https://www.cnblogs.com/sdau--codeants/p/3306909.html
Copyright © 2011-2022 走看看