UVa 1391 Astronauts (2SAT)

來源:互聯網
上載者:User

標籤:style   blog   http   color   os   io   for   ar   

題意:給出一些宇航員他們的年齡,x是他們的平均年齡,其中A任務只能給年齡大於等於x的人,B任務只能給小於x的人,C任務沒有限制。再給出m對人,他們不能同任務。現在要你輸出一組符合要求的任務安排。

思路:2SAT。

設Ai表示第i個人的任務,如果i的年齡大於等於x,那麼Ai=true表示分到A任務,flase表示分到C任務。如果i年齡小於x則Ai=true表示分到B任務,flase表示分到C任務。

考慮對於這m對裡的每對人,如果他們是同組的,那麼(Ai並非Aj)或(非Ai並Aj)等價於 (非Ai或非Aj)並(Ai或Aj)

如果他們是不同組的,那麼只要他們都不是C任務就行,即非(非Ai並非Aj)等價於(Ai或Aj)

這樣就可以用2SAT做了。注意平均年齡x要用浮點數。

我用的是LRJ的模板,2i表示Ai=false,2i+1表示Ai=true

#include <cstdio>#include <cmath>#include <vector>#include <cstring>using namespace std;const int maxn =100005;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;    }};TwoSAT solver;int age[100005];int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF)    {        if(!n&&!m) break;        double x=0;        for(int i=0; i<n; ++i)        {            scanf("%d",&age[i]);            x+=age[i];        }        x/=n;        solver.init(n);        for(int i=0; i<m; ++i)        {            int a,b;            scanf("%d%d",&a,&b);            a--;            b--;            if((age[a]>=x&&age[b]>=x)||(age[a]<x&&age[b]<x))            {                solver.add_clause(a,0,b,0);                solver.add_clause(a,1,b,1);            }            else                solver.add_clause(a,1,b,1);        }        if(!solver.solve()) puts("No solution.");        else        {            for(int i=0; i<2*n; i+=2)                if(solver.mark[i])                    printf("C\n");                else                    printf("%c\n",age[i/2]>=x?‘A‘:‘B‘);        }    }    return 0;}
View Code

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.