zoukankan      html  css  js  c++  java
  • UVA1391/LA3713 Astronauts

    题意:有A、B、C3个任务分配给n个宇航员,其中每个宇航员恰好分配一个任务。假设n个宇航员的平均年龄为x,只有年龄大于x的才能领取A任务;只有年龄严格小于x的才能领取B任务,而任务C没有限制。有m对宇航员相互讨厌,因此不能分配同一任务。求出是否能找出符合的任务方案。(转自http://blog.csdn.net/u011345461/article/details/39779721)

    题目看上去是ABC三个选择,实际上每个人只有两个选择。对于每对矛盾,如果两个人选择相同(即均为BC或均为AC),那么一个选C另一个必选B(A),另一个选C一个必选B(A),一个选B(A)另一个必选C,另一个选B(A)一个必选C;如果两个人选择不同(一个AC一个BC),那么一个选C另一个必选B,另一个选C一个必选A。

    这题数据范围很大,好奇nm做法是怎么水过去的。。

    正解是tarjan缩点,标记每个块的对立块,建立反图,对反图top排序,对于当前的块x,删除对立块和对立块在反图上的出边,并把当前快入队。最后看队列里没被删除的块即为答案块。把点扫一扫看看在不在答案块,在的话这个点的值代表选A(B)还是选C就是这个人的选择

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <queue>
      7 #include <vector>
      8 #include <map>
      9 #include <string> 
     10 #include <cmath> 
     11 #define min(a, b) ((a) < (b) ? (a) : (b))
     12 #define max(a, b) ((a) > (b) ? (a) : (b))
     13 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
     14 template<class T>
     15 inline void swap(T &a, T &b)
     16 {
     17     T tmp = a;a = b;b = tmp;
     18 }
     19 inline void read(int &x)
     20 {
     21     x = 0;char ch = getchar(), c = ch;
     22     while(ch < '0' || ch > '9') c = ch, ch = getchar();
     23     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
     24     if(c == '-') x = -x;
     25 }
     26 const int INF = 0x3f3f3f3f;
     27 const int MAXN = 300000 + 10;
     28 struct Edge
     29 {
     30     int u,v,nxt;
     31     Edge(int _u, int _v, int _nxt){u = _u;v = _v;nxt = _nxt;}
     32     Edge(){}
     33 }edge1[MAXN << 3], edge2[MAXN << 3];
     34 int head1[MAXN], head2[MAXN], vis[MAXN], tag[MAXN], rebelong[MAXN], del[MAXN], q[MAXN], he, ta, indeg[MAXN], cnt1, cnt2, n, m, belong[MAXN], group, b[MAXN], bb[MAXN], dfn[MAXN], stack[MAXN], top, low[MAXN], dfst, year[MAXN], x, tmp1, tmp2;
     35 inline void insert1(int a, int b){edge1[++ cnt1] = Edge(a, b, head1[a]), head1[a] = cnt1;}
     36 inline void insert2(int a, int b){edge2[++ cnt2] = Edge(a, b, head2[a]), head2[a] = cnt2;}
     37 void dfs(int u)
     38 {
     39     b[u] = bb[u] = 1, dfn[u] = low[u] = ++ dfst, stack[++ top] = u;
     40     for(int pos = head1[u];pos;pos = edge1[pos].nxt)
     41     {
     42         int v = edge1[pos].v;
     43         if(!b[v]) dfs(v), low[u] = min(low[u], low[v]);
     44         else if(bb[v]) low[u] = min(low[u], dfn[v]); 
     45     }
     46     if(low[u] == dfn[u])
     47     {
     48         int now = -1;++ group;
     49         while(now != u) now = stack[top --], bb[now] = 0, belong[now] = group;
     50     }
     51 } 
     52 void rebuild()
     53 {
     54     memset(indeg, 0, sizeof(indeg)), memset(head2, 0, sizeof(head2));
     55     for(int i = 1;i <= cnt1;++ i)
     56         if(belong[edge1[i].u] != belong[edge1[i].v])
     57             insert2(belong[edge1[i].v], belong[edge1[i].u]), ++ indeg[belong[edge1[i].u]];
     58 }
     59 void tarjan()
     60 {
     61     memset(belong, 0, sizeof(belong)), memset(dfn, 0, sizeof(dfn)), memset(low, 0, sizeof(low)), group = 0, memset(b, 0, sizeof(b)), memset(bb, 0, sizeof(bb)), dfst = 0, top = 0, memset(rebelong, 0, sizeof(rebelong));
     62     for(int i = 1;i <= n;++ i) if(!b[i << 1]) dfs(i << 1);
     63     for(int i = 1;i <= n;++ i) if(!b[i << 1 | 1]) dfs(i << 1 | 1);
     64     for(int i = 1;i <= n;++ i) rebelong[belong[i << 1]] = belong[i << 1 | 1], rebelong[belong[i << 1 | 1]] = belong[i << 1];
     65     rebuild();
     66 }
     67 void top_sort()
     68 {
     69     he = 0, ta = 0, memset(del, 0, sizeof(del));
     70     for(int i = 1;i <= group;++ i) if(!indeg[i]) q[ta ++] = i;
     71     while(he < ta)
     72     {
     73         int now = q[he ++], renow = rebelong[now];
     74         if(del[now]) continue; del[renow] = 1;
     75         for(int pos = head2[renow];pos;pos = edge2[pos].nxt)
     76         {
     77             int v = edge2[pos].v;
     78             del[v] = 1;
     79             for(int poss = head2[v];poss;poss = edge2[poss].nxt) -- indeg[edge2[poss].v];
     80         }
     81         for(int pos = head2[now];pos;pos = edge2[pos].nxt) 
     82         {
     83             int v = edge2[pos].v;
     84             if(del[v]) continue;
     85             -- indeg[v];
     86             if(!indeg[v]) q[ta ++] = v;
     87         }
     88     }
     89 }
     90 int main()
     91 {
     92     while(scanf("%d %d", &n, &m) != EOF && n && m)
     93     {
     94         cnt1 = 0, memset(head1, 0, sizeof(head1)), x = 0;
     95         for(int i = 1;i <= n;++ i) read(year[i]), x += year[i];
     96         if(x % n == 0) x = x / n;
     97         else x = x / n + 1;
     98         for(int i = 1;i <= n;++ i) year[i] = year[i] >= x;  //year[i] = 1 表示选A或C  year[i] = 0 表示选B或C 
     99         for(int i = 1;i <= m;++ i)
    100         {
    101             read(tmp1), read(tmp2);
    102             if(year[tmp1] == year[tmp2]) insert1(tmp1 << 1 | 1, tmp2 << 1), insert1(tmp2 << 1 | 1, tmp1 << 1), insert1(tmp1 << 1, tmp2 << 1 | 1), insert1(tmp2 << 1, tmp1 << 1 | 1);
    103             else insert1(tmp1 << 1 | 1, tmp2 << 1), insert1(tmp2 << 1 | 1, tmp1 << 1); 
    104         }
    105         tarjan();
    106         int flag = 0;
    107         for(int i = 1;i <= n;++ i) if(belong[i << 1 | 1] == belong[i << 1]) flag = 1;
    108         if(flag)
    109         {
    110             printf("No solution.
    ");
    111             continue;
    112         }
    113         top_sort(); 
    114         memset(vis, 0, sizeof(vis)), memset(tag, 0, sizeof(tag));
    115         for(int i = 0;i < ta;++ i) if(!del[q[i]]) vis[q[i]] = 1;
    116         for(int i = 1;i <= n;++ i) 
    117             if(vis[belong[i << 1]]) tag[i] = 0;
    118             else tag[i] = 1;
    119         for(int i = 1;i <= n;++ i)
    120             if(year[i] && !tag[i]) printf("A
    ");
    121             else if(!year[i] && !tag[i]) printf("B
    ");
    122             else printf("C
    ");
    123     }
    124     return 0;
    125 }
    UVA1391/LA3713
  • 相关阅读:
    linux /mac 下 go环境变量配置
    idea常用快捷键
    《Redis开发与运维》读书笔记
    【Zookeeper】windows环境下zookeeper安装
    【Linux命令】top命令
    【Linux命令】grep命令
    【Linux命令】ps命令
    【Java并发编程】23、ConcurrentHashMap原理分析(1.7和1.8版本对比)
    【Java深入研究】10、红黑树
    《大型网站技术架构 核心原理与案例分析》读书笔记
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8393061.html
Copyright © 2011-2022 走看看