poj 1112 Team Them Up!

原创 2012年03月21日 21:40:17

题目链接:http://poj.org/problem?id=1112

题目大意:把n个人分成两组;组内成员相互之间必须认识。做法是如果两个人不是相互都认识则建边,用dfs搜出连通分量,然后dp,具体见其他人的博客。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<queue>
#include<algorithm>
#include<vector>
#include<stack>
#include<list>
#include<iostream>
#include<map>
using namespace std;
#define inf 0x3f3f3f3f
#define Max 110
int max(int a,int b)
{
	return a>b?a:b;
}
int min(int a,int b)
{
	return a<b?a:b;
}
int f[Max],id;
int dp[Max][Max],mp[Max][Max];
int num[Max][2];
int cnt,tmp,co[Max],vst[Max],eid,p[Max],flag;
struct node
{
    int to,next;
}e[2*Max*Max];
void addedge(int u,int v)
{
    e[eid].to=v;
   // e[eid].len=len;
    e[eid].next=p[u];
    p[u]=eid++;
}
void dfs(int u)
{
    int v,i;
    for(i=p[u];i!=-1;i=e[i].next)
    {
        v=e[i].to;
        if(co[v]==co[u])
        {
            flag=1;
            return;
        }
        else if(co[v]!=-1)
            continue;
        v=e[i].to;
        f[v]=id;
        co[v]=co[u]^1;
        num[id][co[v]]++;
        dfs(v);
        if(flag)
            return;
    }
    if(flag)
        return;
}
int main()
{
    int n,u,v,i,j;
   // while(!=EOF)
   // {
        scanf("%d",&n);
        memset(co,-1,sizeof(co));
        memset(p,-1,sizeof(p));
        eid=0;
        for(i=1;i<=n;i++)
        {
            while(scanf("%d",&v),v)
            {
                mp[i][v]=1;
            }
        }
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
            {
                if(mp[i][j]&&mp[j][i])
                    continue;
                if(i==j)
                    continue;
                addedge(i,j);
                addedge(j,i);
            }
        id=1;
        flag=0;
       // printf("yyyy");
        for(i=1;i<=n;i++)
        {
            if(co[i]==-1)
            {
                co[i]=0;
                num[id][0]++;
                f[i]=id;
                dfs(i);
               // printf("cccc");
                if(flag==1)
                {
                    printf("No solution\n");
                    break;
                }
                id++;
            }
        }
        if(flag)return 0;;
        dp[0][0]=1;
        for(i=1;i<id;i++)
        {
            //int tmp1=num[id][0];
           // int tmp2=num[id][1];
            for(j=0;j<=n/2;j++)
            {
                if(dp[i-1][j])
                {
                    if(j+num[i][0]<=n/2)
                        dp[i][j+num[i][0]]=1;
                    if(j+num[i][1]<=n/2)
                        dp[i][j+num[i][1]]=1;
                }
            }
        }
        for(i=n/2;i>=0;i--)
        {
            if(dp[id-1][i]==1)
            {
                tmp=i;
                cnt=i;
                break;
            }
        }
        for(i=id-1;i>=1;i--)
        {
            int typ;
            if(tmp-num[i][0]>=0&&dp[i-1][tmp-num[i][0]])
            {
                typ=0;
                tmp=tmp-num[i][0];//continue;
            }
            else if(tmp-num[i][1]>=0&&dp[i-1][tmp-num[i][1]])
            {
                tmp=tmp-num[i][1];
                typ=1;
            }
            for(j=1;j<=n;j++)
            {
                if(f[j]==i&&co[j]==typ)
                    vst[j]=1;
            }
        }
        printf("%d ",cnt);
        for(i=1;i<=n;i++)
        {
            if(vst[i])
                printf("%d ",i);
        }
        puts("");
        printf("%d ",n-cnt);
        for(i=1;i<=n;i++)
        {
            if(!vst[i])
                printf("%d ",i);
        }
        puts("");
  //  }
}

 

 

Poj 1112 Team Them Up!

首先分析这道题目,题目给出的是一个有向图,即如果有A认识B,但不一定有B认识A。但是在所分配的组里面,任意两个人都要互相认识。 1、 先读入数据建立有向图,然后对这个有向图进行处理,如果两个点之...
  • u013007900
  • u013007900
  • 2014年08月12日 10:45
  • 561

POJ 1112 Team Them Up!

http://poj.org/problem?id=1112 题意:一共N个人,给出每个人和其余人是否认识,把所有人分成两组。 要求1)每一个人 属于其中一组。 2)每组必须有人  3)每组内的所有人...
  • u011065479
  • u011065479
  • 2013年11月08日 17:14
  • 709

POJ 1112 Team Them Up

Team Them Up!Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 3404 Accepted: 901 Special Ju...
  • bobten2008
  • bobten2008
  • 2009年09月12日 17:39
  • 1141

POJ 1112 Team Them Up! 笔记

N个人编号1到N。分成两队,每队成员之间相互认识,两队规模尽可能接近。求如何分配。...
  • woniupengpeng
  • woniupengpeng
  • 2017年05月04日 23:27
  • 331

poj 1112 Team Them Up! (补图+dp)

Team Them Up! Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7616   ...
  • clover_hxy
  • clover_hxy
  • 2016年10月30日 23:31
  • 211

图论+dp poj 1112 Team Them Up!

题目链接: http://poj.org/problem?id=1112 题目大意: 有编号为1~n的n个人,给出每个人认识的人的编号,注意A认识B,B不一定认识A,让你将所有的人分成两组,要求...
  • cc_again
  • cc_again
  • 2013年08月21日 21:56
  • 1225

poj 1112 Team Them Up! 二分图染色+dp

题意: 给n个人和一些认识关系,要将这n个人分成两队,每队的人之间都互相认识,求一种方案使两队的人数差最小。 分析: 对原图求逆得到新图g,g中如果有边(a,b),那么a,b不能在一个队,对新图...
  • sepNINE
  • sepNINE
  • 2014年12月17日 12:03
  • 526

POJ 1112 Team Them Up! DP

题目大意: 现有n个人,先把
  • ACMmaxx
  • ACMmaxx
  • 2014年07月18日 19:47
  • 320

UVA1627TeamThemUp

本题最巧妙的地方,在于这个dp函数的设计。与之前做过的题的dp函数都不同,本题dp函数中的两个决策是在数组下标中完成的,而数组的值仅仅充当合法性的依据。 dfs的威力在枚举连通分量时,...
  • qq_16603365
  • qq_16603365
  • 2017年08月09日 23:13
  • 82

Uva-1627-Team them up!

这个题最开始打算是暴力的,结果发现不行。后来想DP的
  • z309241990
  • z309241990
  • 2014年07月17日 10:15
  • 692
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj 1112 Team Them Up!
举报原因:
原因补充:

(最多只允许输入30个字)