首页 > 代码库 > UVALive3713_Astronauts
UVALive3713_Astronauts
有n个宇航员,根据年龄限制,所有宇航员只能从事A或B中的一种任务,所有人都可以从事C的任务。有的宇航员之间相互讨厌,不能分在一组,求出一种满足条件的分配方案。
2sat。mark[]中i+i和i+i+1分别表示i从事C工作或者他的特有工作。
对于仇恨关系,我们可以知道U和V两个人不能同时从事C工作。于是加边 (U+U,V+V+1),(V+V,U+U+1)。
同时,如果这两个人的特有工作相同,那么还需要加边(U+U+1,V+V),(V+V+1,U+U)。
召唤代码君:
#include <iostream>#include <cstdio>#include <cstring>#define maxn 5555550using namespace std;int age[maxn],n,m;int next[maxn],to[maxn],first[maxn],edge;bool mark[maxn];//0 C \ 1 A|Bint Q[maxn],top;double avg;void addedge(int U,int V){ edge++; to[edge]=V,next[edge]=first[U],first[U]=edge;}bool dfs(int cur){ if (mark[cur^1]) return false; if (mark[cur]) return true; Q[++top]=cur,mark[cur]=true; for (int i=first[cur]; i!=-1; i=next[i]) if (!dfs(to[i])) return false; return true;}int main(){ int U,V; while (scanf("%d%d",&n,&m) && (n|m)) { avg=0,edge=-1; for (int i=1; i<=n; i++) { scanf("%d",&age[i]); avg+=age[i]; mark[i+i]=mark[i+i+1]=false; first[i+i]=first[i+i+1]=-1; } avg/=n; while (m--) { scanf("%d%d",&U,&V); addedge(U+U,V+V+1),addedge(V+V,U+U+1); if ((age[U]<avg)^(age[V]<avg)) continue; addedge(U+U+1,V+V),addedge(V+V+1,U+U); } bool flag=true; for (int i=1; i<=n; i++) { if (mark[i+i] || mark[i+i+1]) continue; top=0; if (!dfs(i+i)) { while (top) mark[Q[top--]]=false; if (!dfs(i+i+1)) { flag=false; break; } } } if (flag) { for (int i=1; i<=n; i++) if (mark[i+i]) printf("C\n"); else printf("%c\n",age[i]>=avg?‘A‘:‘B‘); } else puts("No solution."); } return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。