LA 3713 Astronauts
给个题目链接:
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1714
显然每个人只有两种选择:C或者A/B。而且后一种只和这个人的年龄有关。
这就是一个很显然的2-SAT模型了,显然有矛盾的不能都选C,如果两个人的年龄段还一样,那就更悲剧了,也不能同时选A/B。
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<vector> #include<cstring> #define pb push_back #define ll long long #define maxn 200005 #define M(x) memset(x,0,sizeof(x)) using namespace std; int n,m; struct TOW_SAT{ vector<int> g[maxn]; int tp[maxn],age[maxn]; int tot,node[maxn],num; bool mark[maxn<<1|1]; inline void init(){ for(int i=(n<<1)-1;i>=0;i--) g[i].clear(); M(tp),M(age); M(mark); tot=num=0; } inline void add(int x,int y){ int Cx=x<<1,Ax=Cx+1; int Cy=y<<1,Ay=Cy+1; g[Cx].pb(Ay),g[Cy].pb(Ax); if(tp[x]==tp[y]){ g[Ax].pb(Cy); g[Ay].pb(Cx); } } bool dfs(int x){ if(mark[x^1]) return 0; if(mark[x]) return 1; mark[x]=1,node[++num]=x; for(int i=g[x].size()-1;i>=0;i--) if(!(dfs(g[x][i]))) return 0; return 1; } inline bool work(){ int cl=n<<1; for(int i=0;i<cl;i+=2) if(!mark[i]&&!mark[i+1]){ num=0; if(!dfs(i)){ while(num) mark[node[num--]]=0; if(!dfs(i+1)) return 0; } } return 1; } inline void solve(){ init(); for(int i=0;i<n;i++){ scanf("%d",age+i); tot+=age[i]; } for(int i=0;i<n;i++) if(age[i]*n>=tot) tp[i]=1; int uu,vv; for(int i=1;i<=m;i++){ scanf("%d%d",&uu,&vv); uu--,vv--,add(uu,vv); } if(!work()) puts("No solution"); else{ for(int i=0;i<n;i++){ if(mark[i<<1]) puts("C"); else if(tp[i]) puts("A"); else puts("B"); } } } }mine; int main(){ while(scanf("%d%d",&n,&m)==2&&n&&m) mine.solve(); return 0; }
我爱学习,学习使我快乐