hdu3715 2-sat+二分

Go Deeper

题意:确定一个0/1数组(size:n)使得满足最多的条件数。条件在数组a,b,c给出。

吐槽:哎,一水提,还搞了很久!关键是抽象出题目模型(如上的一句话)。以后做二sat:有哪些是点,哪些是条件,分清!,然后注意细节。这次居然因为里面一个小错误:

判断有无解的时候,i与i+1是否在一个SCC中的时候,i居然没有每次+2!而是++!傻X了。。。囧!还一直以为自己二分写错。。。

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxv=402;//maxe=500000;
int dfn[maxv];int low[maxv];int vis[maxv];int scc[maxv];int ins[maxv];stack<int>sta;
int times=0; int numb=0;
vector<vector<int> >e(maxv);
void tarjan(int u)
{
     dfn[u]=low[u]=times++;
     ins[u]=1;
     sta.push(u);
     for(int i=0;i<e[u].size();i++)
     {
         int v=e[u][i];
         if(!vis[v])
         {
             vis[v]=1;
             tarjan(v);
             if(low[v]<low[u])low[u]=low[v];
         }
         else if(ins[v]&&dfn[v]<low[u])
            low[u]=dfn[v];
     }
     if(low[u]==dfn[u])
     {
         numb++;
         int cur;
         do{
             cur=sta.top();
             sta.pop();
             ins[cur]=0;
             scc[cur]=numb;
         }while(cur!=u);
     }
}
int n,m;int a[10005],b[10005],c[10005];
void init()
{
    numb=times=0;
    for(int i=0;i<maxv;i++)
      {
         scc[i]=ins[i]=dfn[i]=low[i]=vis[i]=0;
         e[i].clear();
      }
}
bool build_solve(int x)
{
    init();
    for(int i=0;i<=x;i++)
    {
        if(c[i]==2)
        {
            e[2*a[i]+1].push_back(2*b[i]);
            e[2*b[i]+1].push_back(2*a[i]);
        }
        else if(c[i]==1)
        {
            e[2*a[i]].push_back(2*b[i]);
            e[2*b[i]].push_back(2*a[i]);
            e[2*a[i]+1].push_back(2*b[i]+1);
            e[2*b[i]+1].push_back(2*a[i]+1);
        }
        else if(c[i]==0)
        {
            e[2*a[i]].push_back(2*b[i]+1);
            e[2*b[i]].push_back(2*a[i]+1);
        }
    }
    for(int i=0;i<=2*n-1;i++)
    {
        if(!vis[i])
        {
            vis[i]=1;
            tarjan(i);
        }
    }
   for(int i=0;i<=2*n-2;i+=2)            //开始写成i++!!!!WA到跪!
        if(scc[i]==scc[i+1])
            return 0;
  return 1;
}
void readin()
{
    for(int i=0;i<m;i++)
        scanf("%d%d%d",&a[i],&b[i],&c[i]);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        init();
        readin();
        int l=0,r=m,mid;
        while(l+1<r)
        {
            mid=(l+r)/2;
            if(build_solve(mid))
                l=mid;
            else
                r=mid;
        }
        printf("%d\n",l+1);
    }
    return 0;
}

hdu3715 2-sat+二分

时间: 2025-01-04 22:03:56

hdu3715 2-sat+二分的相关文章

HDU3715(二分+2-SAT)

Go Deeper Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 3184    Accepted Submission(s): 1035 Problem Description Here is a procedure's pseudocode: go(int dep, int n, int m)beginoutput the valu

LA 3211 飞机调度(2—SAT)

https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间为E,晚着陆时间为L,不得在其他时间着陆.你的任务是为这些飞机安排着陆方式,使得整个着陆计划尽量安全.换句话说,如果把所有飞机的实际着陆时间按照从早到晚的顺序排列,相邻两个着陆时间间隔的最小值. 思路: 二分查找最大值P,每次都用2—SAT判断是否可行. 1 #include<iostream>

hdu-----(1179)Ollivanders: Makers of Fine Wands since 382 BC.(二分匹配)

Ollivanders: Makers of Fine Wands since 382 BC. Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 935    Accepted Submission(s): 523 Problem Description In Diagon Alley ,there is only one Wand-se

ZOJ 3717 Balloon (二分+2-sat)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3717 2-sat版题 对半径R进行二分,将二分得到的R用2-sat判,如果2R<dis(i,j),则建边add_and_zero(i,j),然后看是否有解 1 // #pragma comment(linker, "/STACK:102400000,102400000") 2 #include <cstdio> 3 #include <i

2—SAT问题

现有一个由N个布尔值组成的序列A,给出一些限制关系,比如A[x] AND A[y]=0.A[x] OR A[y] OR A[z]=1.A[x] XOR A[y]=0等,要确定A[0..N-1]的值,使得其满足所有限制关系.这个称为SAT问题,特别的,若每种限制关系中最多只对两个元素进行限制,则称为2-SAT问题. 对于x.y有11种关系,将其拆点2x(假),2x+1(真).对于x为假或者y为假这样的条件,我们连两条有向边2x+1->2y.2y+1->2x,注意这里是有向边以及边的起点和终点的关

hdu1179Ollivanders: Makers of Fine Wands since 382 BC. (二分最大匹配)

Problem Description In Diagon Alley ,there is only one Wand-seller,peeling gold letters over the door read Ollivanders: Makers of Fine Wands since 382 BC.A single wand lay on a faded purple cushion in the dusty window. A tinkling bell rang somewhere

UVALive - 3211 (2-SAT + 二分)

layout: post title: 训练指南 UVALive - 3211 (2-SAT + 二分) author: "luowentaoaa" catalog: true mathjax: true tags: - 2-SAT - 图论 - 训练指南 Now or later UVALive - 3211 题意 n架飞机,每架可选择两个着落时间.安排一个着陆时间表,使得着陆间隔的最小值最大 题解 二分查找最大值P,每次都用2-SAT判断是否可行. #include<bits

2.1 二分分类

本周学习神经网络编程的基础知识 构建神经网络,有些技巧是非常重要 神经网络的计算过程中,通常有一个正向的过程(正向传播步骤),接着会有一个反向步骤(反向传播步骤), 为什么神经网络的计算可以分为前向传播和反向传播两个分开的过程?本周课程通过使用logistic回归来阐述,以便于能够更好的理解, logistic回归是一个用于二分分类的算法 比如有一个二分分类问题的例子, 假如有一张图像作为输入是这样的,你想输出识别此图的标签,如果是猫,输出1,如果不是,则输出0 使用y来表示输出的结果标签, 来

二分查找

递归版(在区间[x, y)中找v的位置) 1 //递归版二分查找 2 int bsearch(int * A, int x, int y, int v) 3 { 4 5 if(v<a[x] || v>a[y-1]) return -1; 6 int m = x + (y-x)/2; //此处能不能用int m = (x+y)/2,需要仔细考虑(暂时想不到原因) 7 if(A[m]==v) return m; 8 else if(A[m]>v) return bsearch(A, x, m