zoukankan      html  css  js  c++  java
  • POJ 1112Team Them Up!图论+DP

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

    题意是把一些人分成两组,要求每一组的人必须互相认识,并且两组的人数尽量的接近,如果我们用认识的关系进行建图,那么这道题将会相当麻烦,如果用不认识的关系建图,那么不认识人的两个人之间连一条边,可以把这些点分为一个二部图,然后对二部图进行染色标记,如果有不认识的两个人分在了同一组,那么就是无解的情况,否则,利用DP求解一个离n/2最近的值,并且记录路径

    View Code
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #define N 105
      5 #define bug printf("hello\n");
      6 using namespace std;
      7 int Abs(int a)
      8 {
      9     return a<0?-a:a;
     10 }
     11 int vis[N],p[N],s[N];
     12 bool map[N][N];
     13 int head[N],num;
     14 int n;
     15 struct node
     16 {
     17     int v,next;
     18 };
     19 node e[N*N];
     20 int dp[N][N];
     21 int ans[N*3];
     22 int mark[N][N];
     23 void add(int u,int v)
     24 {
     25     e[num].v=v,e[num].next=head[u],head[u]=num++;
     26 }
     27 void init()
     28 {
     29     memset(head,-1,sizeof(head));
     30     memset(vis,0,sizeof(vis));
     31     memset(dp,0,sizeof(dp));
     32     memset(mark,0,sizeof(mark));
     33     memset(map,0,sizeof(map));
     34     memset(ans,0,sizeof(ans));
     35     num=0;
     36 }
     37 int dfs(int u,int kind,int f)
     38 {
     39     int i,v;
     40     vis[u]=2*kind+f;
     41     if(f==-1)
     42     p[kind]++;
     43     else
     44     s[kind]++;
     45     for(i=head[u];i>=0;i=e[i].next)
     46     {
     47         v=e[i].v;
     48         if(vis[u]==vis[v])
     49         return 1;
     50         if(vis[v]==0)
     51         if(dfs(v,kind,-1-f)) return 1;
     52     }
     53     return 0;
     54 }
     55 void solve()
     56 {
     57     int i,j,u,v,k,so;
     58     k=0;
     59     for(i=1;i<=n;i++)
     60     {
     61         if(vis[i]==0)
     62         {
     63             k++;
     64             if(dfs(i,k,-1))
     65             break;
     66         }
     67     }
     68     if(i<=n)
     69     printf("No solution\n");
     70     else
     71     {
     72         dp[0][0]=1;
     73         for(i=0;i<k;i++)
     74         for(j=0;j<=n;j++)
     75         {
     76             if(dp[i][j])
     77             {
     78                 dp[i+1][j+p[i+1]]=1;
     79                 dp[i+1][j+s[i+1]]=1;
     80                 mark[i+1][j+p[i+1]]=0;
     81                 mark[i+1][j+s[i+1]]=1;
     82             }
     83         }
     84         j=n;
     85         for(i=1;i<=n;i++)
     86         {
     87             if(dp[k][i])
     88             {
     89                 if(Abs(i-n+i)<j)//本应该是i-n/2这里扩大二倍
     90                 {
     91                     j=Abs(i-n+i);
     92                     so=i;
     93                 }
     94             }
     95         }
     96         for(i=k;i>=1;i--)//寻找路径
     97         {
     98             if(mark[i][so]==0)
     99             {
    100                 ans[2*i-1]=1;
    101                 so-=p[i];
    102             }
    103             else
    104             {
    105                 ans[2*i]=1;
    106                 so-=s[i];
    107             }
    108         }
    109         j=0;
    110         for(i=1;i<=n;i++)
    111         if(ans[vis[i]])
    112         j++;
    113         printf("%d ",j);
    114         for(i=1;i<=n;i++)
    115         if(ans[vis[i]])
    116         printf("%d ",i);
    117         printf("\n");
    118         printf("%d ",n-j);
    119         for(i=1;i<=n;i++)
    120         if(!ans[vis[i]])
    121         printf("%d ",i);
    122         printf("\n");
    123     }
    124 }
    125 int main()
    126 {
    127     init();
    128     int i,j,u,v;
    129     scanf("%d",&n);
    130     for(i=1;i<=n;i++)
    131     {
    132         while(scanf("%d",&v)&&v)
    133         map[i][v]=true;
    134     }
    135     for(i=1;i<=n;i++)
    136     for(j=1;j<=n;j++)
    137     {
    138         if(i!=j&&!(map[i][j]&&map[j][i]))
    139         add(i,j);
    140     }
    141     solve();
    142     return 0;
    143 }
  • 相关阅读:
    【转】hadoop中map和reduce的数量设置问题
    【转】MapReduce原理与设计思想
    eclipse中svn插件在线安装方式
    redis配置文件详解
    Hibernate_Validator学习
    WebService入门实例教程
    Http状态码大全(来自菜鸟教程)
    Java编程规则
    Java和C++的对比
    Java实现OOP(面向对象编程)
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2655776.html
Copyright © 2011-2022 走看看