zoukankan      html  css  js  c++  java
  • LA 3713 宇航员分组

    https://vjudge.net/problem/UVALive-3713

    题意:

    有A、B、C 3个任务要分配给n个宇航员,其中每个宇航员恰好要分配一个任务。设所有n个宇航员的平均年龄为x,只有年龄大于或等于x的宇航员才能分配任务A;只有年龄严格小于x的宇航员才能分配任务B,而任务C没有限制。有m对宇航员相互讨厌,因此不能分配到同一任务。编程找出一个满足上述所有要求的任务分配方案。

    思路:

    每个宇航员要么选C,要么选A和B当中的一个(看年龄大小)。

    对m对相互厌恶的宇航员拆点连边。

    如果他们属于同一个类型,那么Xi,Xj必须不同,Xi为真或Xj为真,Xi为假或Xj为假。前者表示至少一个为true,后者表示至少一个为false。这样只可能是两者一个为true,一个为false了。如果是不同的类型,那么唯一的冲突就是Xi,Xj均为false(即都去做任务C)。那么只需要“Xi为真或Xj为真”即可排除这种冲突。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<vector>
      6 #include<stack>
      7 #include<queue>
      8 #include<cmath>
      9 #include<map>
     10 using namespace std;
     11 
     12 const int maxn=100000+5;
     13 
     14 int n,m;
     15 int age[maxn];
     16 
     17 struct TwoSAT
     18 {
     19     int n;
     20     vector<int> G[2*maxn];
     21     bool mark[2*maxn];
     22     int S[2*maxn],c;
     23 
     24     bool dfs(int x)
     25     {
     26         if(mark[x^1])  return false;
     27         if(mark[x])  return true;
     28         mark[x]=true;
     29         S[c++]=x;
     30         for(int i=0;i<G[x].size();i++)
     31             if(!dfs(G[x][i]))   return false;
     32         return true;
     33     }
     34 
     35     void init(int n)
     36     {
     37         this->n=n;
     38         for(int i=0;i<2*n;i++)   G[i].clear();
     39         memset(mark,0,sizeof(mark));
     40     }
     41 
     42     void add_clause(int x,int xval,int y,int yval)
     43     {
     44         x = x*2 + xval;
     45         y = y*2 + yval;
     46         G[x^1].push_back(y);
     47         G[y^1].push_back(x);
     48     }
     49 
     50     bool solve()
     51     {
     52         for(int i=0;i<2*n;i+=2)
     53             if(!mark[i] && !mark[i+1])
     54         {
     55             c=0;
     56             if(!dfs(i))
     57             {
     58                 while(c>0)  mark[S[--c]]=false;
     59                 if(!dfs(i+1))   return false;
     60             }
     61         }
     62         return true;
     63     }
     64 }solver;
     65 
     66 bool age_judge(int a,int x)
     67 {
     68     if(a*n>=x)  return true;
     69     else return false;
     70 }
     71 
     72 int main()
     73 {
     74     //freopen("D:\input.txt","r",stdin);
     75     while(~scanf("%d%d",&n,&m)&&n)
     76     {
     77         solver.init(n);
     78         int sum=0;
     79         for(int i=0;i<n;i++)
     80         {
     81             scanf("%d",&age[i]);
     82             sum+=age[i];
     83         }
     84         while(m--)
     85         {
     86             int u,v;
     87             scanf("%d%d",&u,&v);
     88             u--; v--;
     89             solver.add_clause(u,1,v,1);
     90             if(age_judge(age[u],sum)==age_judge(age[v],sum))  solver.add_clause(u,0,v,0);
     91         }
     92         if(!solver.solve())   puts("No solution.");
     93         else for(int i=0;i<n;i++)
     94         {
     95             if(solver.mark[2*i])  puts("C");
     96             else if(age_judge(age[i],sum))  puts("A");
     97             else puts("B");
     98         }
     99     }
    100     return 0;
    101 }
  • 相关阅读:
    如何查看哪些软件或进程占用了网速
    关于str.split(",")中间 什么时候该加\转义
    【转】servlet/filter/listener/interceptor区别与联系
    专题-Delphi/C++ Builder多线程编程与调试
    Android点击图标重新启动问题
    用PHP判断远程图片(文件)是否存在
    php获取目录中的所有文件名
    PHP读取一个目录下的文件个数
    2>&1 的用法说明
    【PHP操作sphinx】
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6805737.html
Copyright © 2011-2022 走看看