zoukankan      html  css  js  c++  java
  • UVA 3713 Astronauts

    The Bandulu Space Agency (BSA) has plans for the following three space missions:
    • Mission A: Landing on Ganymede, the largest moon of Jupiter.
    • Mission B: Landing on Callisto, the second largest moon of Jupiter.
    • Mission C: Landing on Titan, the largest moon of Saturn.
    Your task is to assign a crew for each mission. BSA has trained a number of excellent astronauts;
    everyone of them can be assigned to any mission. However, if two astronauts hate each other, then it
    is not wise to put them on the same mission. Furthermore, Mission A is clearly more prestigious than
    Mission B; who would like to go to the second largest moon if there is also a mission to the largest one?
    Therefore, the assignments have to be done in such a way that only young, inexperienced astronauts go
    to Mission B, and only senior astronauts are assigned to Mission A. An astronaut is considered young
    if their age is less than the average age of the astronauts and an astronaut is senior if their age is at
    least the averageage. Every astronaut can be assigned to Mission C, regardless of their age (but you
    must not assign two astronauts to the same mission if they hate each other).

    题目大意:飞行员分为两种:小于平均年龄的和大于的,小于的可以选择B,C两种space,大于的可以选择A,C两种,存在一些有矛盾的人不希望分在同一组,求一种方案使得不存在矛盾

    解题报告:
    个人理解:twosat的连边,有推导出的意思,依据这个,我们就可以分类讨论进行连边:

    我们设年长的true表示在A,年小的true在B,false都表示在C
    对于不同年龄的(x,y),那么只要不在同在C即可,所以直接两者的false分别连到对方的true
    对于不同年龄的(x,y),他们不能在同一舱内,意味着不能同为false或同为true,所以两者的true分别向false连边的同时,也要false向true连边

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=200055;
    bool mark[N];int n,m,edg[N],head[N],nxt[N<<2],to[N<<2],num=0;
    int gi(){
    	int str=0;char ch=getchar();
    	while(ch>'9' || ch<'0')ch=getchar();
    	while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
    	return str;
    }
    void init(int x,int y,bool tx,bool ty){
    	x=((x-1)<<1)+tx;y=((y-1)<<1)+ty;
    	nxt[++num]=head[x];to[num]=y;head[x]=num;
    }
    int st[N],top=0;
    bool dfs(int x){
    	if(mark[x^1])return false;
    	if(mark[x])return true;
    	mark[x]=true;
    	st[++top]=x;
    	for(int i=head[x];i;i=nxt[i]){
    		if(!dfs(to[i]))return false;
    	}
    	return true;
    }
    bool solve(){
    	int lim=(n<<1);
    	for(int i=0;i<lim;i+=2){
    		top=0;
    		if(!dfs(i)){
    			while(top)mark[st[top--]]=false;
    			if(!dfs(i^1))return false;
    		}
    	}
    	return true;
    }
    void work()
    {
    	int x,y;double sum=0;
    	for(int i=1;i<=n;i++)edg[i]=gi(),sum+=edg[i];
    	sum=sum/(n*1.0);
    	for(int i=1;i<=m;i++){
    		x=gi();y=gi();
    		if((edg[x]>=sum)!=(edg[y]>=sum)){
    			init(x,y,0,1);init(y,x,0,1);
    		}
    		else{
    			init(x,y,1,0);init(x,y,0,1);
    			init(y,x,1,0);init(y,x,0,1);
    		}
    	}
    	bool tmp=solve();
    	if(!tmp)puts("No solution.");
    	else{
    		for(int i=1;i<=n;i++){
    			x=(i-1)<<1;
    			if(mark[x])
    				puts("C");
    			else{
    				if(edg[i]<sum)puts("B");
    				else puts("A");
    			}
    		}
    	}
    }
    void Clear(){
    	memset(head,0,sizeof(head));num=0;
    	memset(mark,0,sizeof(mark));
    }
    int main()
    {
    	while(1){
    		n=gi();m=gi();
    		if(n+m==0)break;
    		work();
    		Clear();
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    YUI(YUIcompressor)压缩参数选项
    js进制转换两则
    软件代码生成工具软工厂V2.0版本上线!欢迎新老用户免费使用!
    软件代码自动化生成工具我们该不该用!
    软件代码生成工具软工厂V2.0版本免费使用地址+教学视频,快速完成开发任务。
    转发在.NET上使用ZeroMQ
    . Net环境下消息队列(MSMQ)对象的应用
    消息队列软件产品大比拼
    ubuntu服务器安装指南
    简单的分布式应用程序日志记录器(logger)-基于MSMQ(消息队列)
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7476795.html
Copyright © 2011-2022 走看看