UvaLive-3713-Astronauts

来源:互联网 发布:淘宝抢购验证码 编辑:程序博客网 时间:2024/05/20 03:38

这个题依然是书中的例题,用2-sat做

分析题意可以知道:

1、对于xi,xj属于同一个类型,可以用2个语句表示其中的结果xi^xj,-xi^-xj。

2、对于xi,xj属于不同类型,那么只可能存在xi=false and xj=false这一种冲突的情况,所以只需要加上-xi^-xj这个限制语句就可以解决这个冲突

代码:

#include<cstdio>#include<cstring>#include<iostream>#include<vector>using namespace std;const int maxn =10e4+10;int n,m,age[maxn];double aveage;struct TwoSAT{    int n;    vector<int> G[maxn*2];    bool mark[maxn*2];    int S[maxn*2],c;    bool dfs(int x)    {if(mark[x^1])    return false;if(mark[x])    return true;mark[x]=true;S[c++]=x;for(int i=0;i<G[x].size();i++)    if(!dfs(G[x][i]))return false;return true;    }    void init(int n)    {this->n=n;for(int i=0;i<n*2;i++)    G[i].clear();memset(mark,0,sizeof(mark));    }    void add_clause(int x,int xval,int y,int yval)    {x=x*2+xval;y=y*2+yval;G[x^1].push_back(y);G[y^1].push_back(x);    }    bool solve()    {for(int i=0;i<n*2;i+=2)    if(!mark[i]&&!mark[i+1])    {c=0;if(!dfs(i)){    while(c>0)mark[S[--c]]=false;    if(!dfs(i+1))return false;}    }return true;    }}solver;int GetType(int h){    return h>=aveage?1:2;}int main(){    while(scanf("%d%d",&n,&m)&&(n+m))    {solver.init(n);double sum=0;for(int i=0;i<n;i++){    scanf("%d",&age[i]);    sum+=age[i];}aveage=sum/n;for(int i=0;i<m;i++){    int ita,itb;    scanf("%d%d",&ita,&itb);    ita--;    itb--;    if(ita==itb)continue;    solver.add_clause(ita,1,itb,1);    if(GetType(age[ita])==GetType(age[itb]))solver.add_clause(ita,0,itb,0);}if(!solver.solve())    printf("No solution.\n");else{    for(int i=0;i<n;i++)    {if(!solver.mark[i*2]){    if(GetType(age[i])==1)printf("A\n");    elseprintf("B\n");}else    printf("C\n");    }}    }    return 0;}


原创粉丝点击