zoukankan      html  css  js  c++  java
  • zoj3422Go Deeper(2-sat + 二分)

    题目请戳这里

    题目大意:

    go(int dep, int n, int m)  
    	   begin  
    	      output the value of dep. 
    	      if dep < m and x[a[dep]] + x[b[dep]] != c[dep] then go(dep + 1, n, m)
    	   end 

    读上面程序段,yy出函数功能。数组a,b,c长度为m,x长度为n。数组a,b中元素范围[0,n - 1],数组c元素为0或1或2。x数组元素为1或0。求能输出的最大的m。

    题目分析:2-sat,还是比较裸的吧。要求最大的m,所以对长度m二分。

    详情请见代码:

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N = 405;
    const int M = 10005;
    
    struct node
    {
        int to,next;
    }g[M];
    int head[N],stack1[N],stack2[N],vis[N],scc[N];
    int n,m,num;
    bool flag;
    int a[M],b[M],c[M];
    void init()
    {
        memset(head,-1,sizeof(head));
        flag = true;
        memset(vis,0,sizeof(vis));
        memset(scc,0,sizeof(scc));
        stack1[0] = stack2[0] = 0;
        num = 0;
    }
    void build(int s,int e)
    {
        g[num].to = e;
        g[num].next = head[s];
        head[s] = num ++;
    }
    void dfs(int cur,int &sig,int &cnt)
    {
        if(flag == false)
            return;
        vis[cur] = ++ sig;
        stack1[++stack1[0]] = cur;
        stack2[++stack2[0]] = cur;
        for(int i = head[cur];~i;i = g[i].next)
        {
            if(!vis[g[i].to])
                dfs(g[i].to,sig,cnt);
            else
            {
                if(scc[g[i].to] == 0)
                    while(vis[stack2[stack2[0]]] > vis[g[i].to])
                        stack2[0] --;
            }
        }
        if(stack2[stack2[0]] == cur)
        {
            stack2[0] --;
            cnt ++;
            do
            {
                scc[stack1[stack1[0]]] = cnt;
                if(scc[stack1[stack1[0]]^1] == cnt)
                {
                    flag = false;
                    return;
                }
            }while(stack1[stack1[0] --] != cur);
        }
    }
    void Gabow()
    {
        int i,sig,cnt;
        sig = cnt = 0;
        for(i = 0;i < n + n && flag;i ++)
            if(!vis[i])
                dfs(i,sig,cnt);
    }
    void solve()
    {
        int l,r,mid;
        int ans,i;
        l = 0;r = m;
        while(l <= r)
        {
            mid = (l + r)>>1;
            init();
            for(i = 0;i < mid;i ++)
            {
                int u = a[i]<<1;
                int v = b[i]<<1;
                if(c[i] == 0)// !=0
                {
                    build(u,v^1);
                    build(v,u^1);
                }
                if(c[i] == 1)// != 1
                {
                    build(u,v);
                    build(v,u);
                    build(u^1,v^1);
                    build(v^1,u^1);
                }
                if(c[i] == 2)// != 2
                {
                    build(u^1,v);
                    build(v^1,u);
                }
            }
            Gabow();
            if(flag)
            {
                ans = mid;
                l = mid + 1;
            }
            else
                r = mid - 1;
        }
        printf("%d
    ",ans);
    }
    int main()
    {
        int i,t;
        scanf("%d",&t);
        while(t --)
        {
            scanf("%d%d",&n,&m);
            for(i = 0;i < m;i ++)
                scanf("%d%d%d",&a[i],&b[i],&c[i]);
            solve();
        }
        return 0;
    }
    


  • 相关阅读:
    oracle 11.2.0.4 ADG+linux+补丁升级11.2.0.4.181016(28204707)
    审计信息清理及审计表迁移时遇到的坑
    与其他schema下表同名视图实验
    Oracle 11gr2 RAC到单实例的DG搭建(落地备份)
    Oracle数据文件名乱码问题
    Vmware12+centos7:固定IP
    Vmware12+OracleLinux5.4+Oracle 11.2.0.3+ASM
    OracleLinux文件名最后带空格生成了新的文件???
    OGG新增DataPump进程下发(多个进程共用队列文件)
    OGG BIGDATA从版本12.2升级到12.3.2.1.1
  • 原文地址:https://www.cnblogs.com/riskyer/p/3348009.html
Copyright © 2011-2022 走看看