zoukankan      html  css  js  c++  java
  • Uva1627 Team them up!

    Team them up!

     https://odzkskevi.qnssl.com/9698e76abf2d161889085123803f9464?v=1508663873

    【题解】

    把“两个人不相互认识”连边,形成若干连通分量

    不难发现每个联通分量进行黑白染色后,必定选黑或选白

    DP[i][j]表示前i个连通块,选j个黑块是否可行

    从dp[n][mid]开始向左右检查即可

    因为边数开小以及偶数n的处理不当RE/WA了很多发

    要用大数据测/对拍/手出数据验证程序的每一部分

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <vector> 
      6 #define min(a, b) ((a) < (b) ? (a) : (b))
      7 #define max(a, b) ((a) > (b) ? (a) : (b))
      8 
      9 inline void swap(int &a, int &b)
     10 {
     11     int tmp = a;a = b;b = tmp;
     12 }
     13 
     14 inline void read(int &x)
     15 {
     16     x = 0;char ch = getchar(), c = ch;
     17     while(ch < '0' || ch > '9')c = ch, ch = getchar();
     18     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
     19     if(c == '-')x = -x;
     20 }
     21 
     22 const int INF = 0x3f3f3f3f;
     23 const int MAXN = 100 + 10;
     24 
     25 struct Edge
     26 {
     27     int u,v,nxt;
     28     Edge(int _u, int _v, int _nxt){u = _u;v = _v;nxt = _nxt;}
     29     Edge(){}
     30 }edge[MAXN * MAXN << 1];
     31 int head[MAXN], cnt;
     32 inline void insert(int a, int b)
     33 {
     34     edge[++cnt] = Edge(a,b,head[a]);
     35     head[a] = cnt;
     36 }
     37 
     38 int t,n,tot,x[MAXN],y[MAXN],b[MAXN],g[MAXN][MAXN],tag,dp[MAXN][MAXN],zhuanyi1[MAXN][MAXN], zhuanyi2[MAXN][MAXN], zhuanyi3[MAXN][MAXN];
     39 std::vector<int> xx[MAXN], yy[MAXN];
     40 
     41 int dfs(int u, int flag)
     42 {
     43     b[u] = flag;
     44     if(flag == 1) ++ x[tot], flag = 2, xx[tot].push_back(u);
     45     else flag = 1, ++ y[tot], yy[tot].push_back(u);
     46     for(register int pos = head[u];pos;pos = edge[pos].nxt)
     47     {
     48         int v = edge[pos].v;
     49         if(!b[v])
     50         {
     51             if(dfs(v, flag))
     52                 return 1;
     53         }
     54         else if(b[v] != flag) 
     55             return 1;
     56     }
     57     return 0;
     58 }
     59 
     60 void dfs2(int p, int q)
     61 {
     62     if(p == 0) return;
     63     b[p] = zhuanyi3[p][q];
     64     dfs2(zhuanyi1[p][q], zhuanyi2[p][q]);
     65 }
     66 
     67 int check(int num)
     68 {
     69     if(!dp[tot][num]) return 0;
     70     printf("%d ", num);
     71     memset(b, 0, sizeof(b));
     72     dfs2(tot, num);
     73     for(register int i = 1;i <= tot;++i)
     74         if(b[i] == 1)
     75             for(register int j = 0;j < xx[i].size();++ j)
     76                 printf("%d ", xx[i][j]);
     77         else
     78             for(register int j = 0;j < yy[i].size();++ j)
     79                 printf("%d ", yy[i][j]);
     80     printf("
    %d ", n - num);
     81     for(register int i = 1;i <= tot;++i)
     82         if(b[i] == 1)
     83             for(register int j = 0;j < yy[i].size();++ j)
     84                 printf("%d ", yy[i][j]);
     85         else
     86             for(register int j = 0;j < xx[i].size();++ j)
     87                 printf("%d ", xx[i][j]);
     88     putchar('
    ');
     89     return 1;
     90 }
     91 
     92 void init() 
     93 {
     94     tot = 0;cnt = 0;tag = 0;
     95     memset(head, 0, sizeof(head));
     96     memset(g, 0, sizeof(g));
     97     memset(b, 0, sizeof(b));
     98     memset(x, 0, sizeof(x));
     99     memset(y, 0, sizeof(y));
    100     memset(dp, 0, sizeof(dp));
    101     memset(zhuanyi1, 0, sizeof(zhuanyi1));
    102     memset(zhuanyi2, 0, sizeof(zhuanyi2));
    103     memset(zhuanyi3, 0, sizeof(zhuanyi3));
    104     for(register int i = 1;i <= n;++ i) xx[i].clear(), yy[i].clear();
    105 }
    106 
    107 int main()
    108 {
    109     read(t);
    110     for(;t;--t)
    111     {
    112         read(n);
    113         init();
    114         for(register int i = 1;i <= n;++ i)
    115         {
    116             int tmp;
    117             read(tmp);
    118             while(tmp)
    119             {
    120                 g[i][tmp] = 1;
    121                 read(tmp);
    122             }
    123         }
    124         for(register int i = 1;i <= n;++ i)
    125             for(register int j = i + 1;j <= n;++ j)
    126                 if(!g[i][j] || !g[j][i])
    127                     insert(i, j), insert(j, i);
    128         for(register int i = 1;i <= n;++ i)
    129             if(!b[i])
    130             {
    131                 ++ tot;
    132                 if(dfs(i, 1))
    133                 {
    134                     printf("No solution
    
    ");
    135                     tag = 1;
    136                     break;
    137                 }
    138             }
    139         if(tag)continue;
    140         dp[0][0] = 1;
    141         //dp[i][j]表示前i个连通分量,标号为1的有j个是否可行 
    142         for(register int i = 1;i <= tot;++ i)
    143             for(register int j = n;j >= 0;-- j)
    144             {
    145                 if(j - x[i] >= 0 && dp[i - 1][j - x[i]])
    146                 {
    147                     zhuanyi1[i][j] = i - 1;
    148                     zhuanyi2[i][j] = j - x[i];
    149                     zhuanyi3[i][j] = 1;
    150                     dp[i][j] = 1;
    151                 }
    152                 else if(j - y[i] >= 0 && dp[i - 1][j - y[i]])
    153                 {
    154                     zhuanyi1[i][j] = i - 1;
    155                     zhuanyi2[i][j] = j - y[i];
    156                     zhuanyi3[i][j] = 2;
    157                     dp[i][j] = 1;
    158                 }
    159             }
    160         int mid = n/2;
    161         if(n & 1)
    162         {
    163             mid += 1;
    164             for(register int i = 0;;++ i)
    165             {
    166                 if(!(i + mid <= n && mid - i > 0)) 
    167                 {
    168                     tag = 1;    
    169                     break;
    170                 }
    171                 if(check(i + mid)) 
    172                 {
    173                     tag = 1;
    174                     break;
    175                 }
    176                 if(check(mid - i)) 
    177                 {
    178                     tag = 1;
    179                     break;
    180                 }
    181             }
    182         }
    183         else
    184         {
    185             for(register int i = 1;i <= mid;++i)
    186             {            
    187                 if(check(mid - i + 1)) 
    188                 {
    189                     tag = 1;
    190                     break;
    191                 }
    192                 if(check(mid + i)) 
    193                 {
    194                     tag = 1;
    195                     break;
    196                 }
    197             }
    198         }
    199         if(!tag)printf("No solution
    ");
    200         printf("
    ");
    201     }
    202     return 0;
    203 }
    UVA1627
  • 相关阅读:
    Windows Server 2003安装VS2010重命名项目崩溃
    分表处理设计思想和实现[转载]
    XSD中如何定义节点(Element)包含属性(Attribute)和上下文(Context)?
    数据库水平切分的原理探讨、设计思路数据库分库,分表,集群,负载均衡器
    域名注册供参考的200个前缀和后缀
    一个 XSD 实例
    了解Javascript中defer
    Asp.net中慎用Page.DataBind()
    C#中相对路径转绝对路径
    Cookies中Secure使用
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7721723.html
Copyright © 2011-2022 走看看