Light OJ 1251 - Forming the Council (2-SAT模板题)

原创 2015年07月10日 00:47:35

传送门:http://lightoj.com/volume_showproblem.php?problem=1251

题目大意:m个人竞选,n个人投票,每个投票里面包含两个数,可正可负,正数代表支持,负数代表反对,为了满足所有投票的要求,求出多少人当选以及当选人的名单。

解题思路:每个投票就是一个2-SAT中的条件,直接套用2-SAT求解即可。

Code:

/*   W          w           w        mm          mm             222222222       7777777777777    */
/*    W        w w         w        m  m        m  m          222        22              7777    */
/*    w        w w         w        m  m        m  m                     22              777     */
/*     w      w   w       w        m    m      m    m                    22              77      */
/*     w      w    w      w        m    m      m    m                 222                77      */
/*      w    w      w    w        m      m    m      m              222                  77      */
/*      w    w      w    w        m      m    m      m            222                    77      */
/*       w  w        w  w        m        m  m        m         222                      77      */
/*       w  w        w  w        m        m  m        m      222                         77      */
/*        ww          ww        m          mm          m     222222222222222             77      */

//#pragma comment(linker, "/STACK:102400000,102400000")
//C++
//int size = 256 << 20; // 256MB
//char *p = (char*)malloc(size) + size;
//__asm__("movl %0, %%esp\n" :: "r"(p));
//G++
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<ctime>
#include<deque>
#include<cmath>
#include<vector>
#include<string>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
#define REP(i,s,t) for(int i=(s);i<=(t);i++)
#define REP2(i,t,s) for(int i=(t);i>=s;i--)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned long ul;

const int maxn=20005;
int T;
int n,m;
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;
    }
    void fuck()
    {
        vector<int>ans;
        ans.clear();
        for(int i=0;i<n*2;i+=2)
        {
            if(mark[i+1])
            {
                //printf("%d\n",i/2+1);
                ans.push_back(i/2+1);
            }
        }
        printf("%d",ans.size());
        for(int i=0;i<ans.size();i++)
        {
            printf(" %d",ans[i]);
        }
        printf("\n");
    }
}solver;
int main()
{
  #ifdef ONLINE_JUDGE
  #else
    freopen("test.in","r",stdin);
  #endif
  int ca=1;
  scanf("%d",&T);
  while(T--)
  {
    scanf("%d%d",&m,&n);
    solver.init(n);
    REP(i,1,m)
    {
        int x,y,xval,yval;
        scanf("%d%d",&x,&y);
        if(x>0)
        {
            x=x-1;
            xval=1;
        }
        else
        {
            x=(-x)-1;
            xval=0;
        }
        if(y>0)
        {
            y=y-1;
            yval=1;
        }
        else
        {
            y=(-y)-1;
            yval=0;
        }
        solver.add_clause(x,xval,y,yval);
    }
    bool flag=solver.solve();
    printf("Case %d: %s\n",ca++,flag?"Yes":"No");
    if(flag)solver.fuck();
  }
  return 0;
}

相关文章推荐

light oj 1251 - Forming the Council (2-SAT + 输出任意解)

题意:n个公民m个议员,n个公民对m个公民进行投票,+i表示希望i号议员留下,-i希望i号议员离开,问是否存在一组解满足全部的n个投票,有的话输出任意一组解。 思路:每个公民的投票a||b建图,!a-...

LightOJ 1251 Forming the Council【2-Sat+逆向拓扑排序输出可行解】好题!

1251 - Forming the Council     PDF (English) Statistics Forum Time Limi...

LightOj 1251 Forming the Council(2-sat)

原题地址:点击打开链接 #include #include #include #include #include using namespace std; int m; int time; int ...

light oj 1236 Pairs Forming LCM(整数分解)

大概题意是找出对于整数对(i,j),他们的lcm为n,这样的整数对有多少。 看了大牛博客才懂,假设lcm(X,Y)=M,分别分解X,Y,M  X=x1^a1*x2^a2... Y=x1^b1*x2^...

hoj 1917 2-sat 模板题

#include #include #include #include #include #include #include #include #include #include #include #...

POJ 3678 Katu Puzzle(2-sat 模板题)

POJ 3678 Katu Puzzle(2-sat 模板题)

HDU 4421 & ZOJ 3556 Bit Magic(2-SAT 位运算 模板题)

HDU 4421 & ZOJ 3556 Bit Magic(2-SAT 位运算 模板题)

HDU 1814 Peaceful Commission(2-sat 模板题输出最小字典序解决方案)

HDU 1814 Peaceful Commission(2-sat 模板题输出最小字典序解)

ZOJ 3656 2-sat模板题

//2012长春现场赛 很裸的2-sat  因为是位运算,所以 把b[i] 的 每一位都利用 2-sat 判断一次。  #include #include #include #include...

哈理工OJ 1251 【带坑的快速幂】【好题】

Marshal's Confusion III Time Limit: 3000 MS Memory Limit: 65536 K Total S...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Light OJ 1251 - Forming the Council (2-SAT模板题)
举报原因:
原因补充:

(最多只允许输入30个字)