现在的位置: 首页 > 综合 > 正文

hdu 3715 (2-SAT+二分)

2018年02月20日 ⁄ 综合 ⁄ 共 1737字 ⁄ 字号 评论关闭

2-SAT+二分,X[ ]每个元素可以为0或1,是否存在这样的数组让程序的输出值最大,

明显的2-SAT,要求最大值就得二分验证,刚开始脑子抽筋的想到只需要前mid出现的X[]满足就可以,

验证的时候写成i<mid,果断wrong了。前mid出现的X[]的下标肯定不是连续的,

所以就只要验证前mid出现的X[]就行了,果然AC。

今天早上看了看程序,发现前mid没出现的X[ ],根本就没有加边,所以肯定会满足,所以也可以验证到n。








#include<stdio.h>
#include<string.h>
#include<stack>
#define N 500
using namespace std;
struct node
{
    int ed,next;
}E[N*N];
struct op
{
    int a,b,c;
}q[10010];
int n,m,low[N],dfs[N],belong[N],ins[N],first[N],num,ans,idx;
void addeage(int x,int y)
{
    E[num].ed=y;
    E[num].next=first[x];
    first[x]=num++;
}
void insit()
{
   memset(dfs,-1,sizeof(dfs));
   memset(low,0,sizeof(low));
   memset(first,-1,sizeof(first));
   memset(belong,0,sizeof(belong));
   ans=idx=num=0;

}
stack<int>Q;
void Tarjan(int x)
{
    int v;
    low[x]=dfs[x]=idx++;
    ins[x]=1;
    Q.push(x);
    for(int p=first[x];p!=-1;p=E[p].next)
    {
        v=E[p].ed;
        if(dfs[v]==-1)
        {
            Tarjan(v);
            low[x]=low[x]>low[v]?low[v]:low[x];
        }
        else if(ins[v]==1)
        {
            low[x]=low[x]>dfs[v]?dfs[v]:low[x];
        }
    }
    if(dfs[x]==low[x])
    {
        ans++;
        do
        {
            v=Q.top();
            Q.pop();
            belong[v]=ans;
            ins[v]=0;
        }while(v!=x);
    }

}
int judge(int d)
{
    insit();
    int i;
    for(i=0;i<d;i++)
    {
        if(q[i].c==0)
        {
            addeage(q[i].a,q[i].b+n);
            addeage(q[i].b,q[i].a+n);
        }
        else if(q[i].c==1)
        {
            addeage(q[i].a+n,q[i].b+n);
            addeage(q[i].b,q[i].a);
            addeage(q[i].b+n,q[i].a+n);
            addeage(q[i].a,q[i].b);
        }
        else if(q[i].c==2)
        {
            addeage(q[i].a+n,q[i].b);
            addeage(q[i].b+n,q[i].a);
        }
    }
    for(i=0;i<2*n;i++)
    {
        if(dfs[i]==-1)
            Tarjan(i);
    }
	/*
	for(i=0;i<d;i++)
    {
        if(belong[q[i].a]==belong[q[i].a+n])
            return 0;
        if(belong[q[i].b]==belong[q[i].b+n])
            return 0;
    }*/
    for(i=0;i<n;i++)
    {
        if(belong[i]==belong[i+n])
            return 0;
    }
    return 1;
}
int main()
{
    int i,mid,t,min,max,mmax;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=0;i<m;i++)
            scanf("%d%d%d",&q[i].a,&q[i].b,&q[i].c);
        min=0;max=m;mmax=min;
        while(min<=max)
        {
            mid=(min+max)/2;
            if(judge(mid))
            {
                if(mmax<mid)mmax=mid;
                min=mid+1;
            }
            else max=mid-1;
        }
        printf("%d\n",mmax);

    }
    return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.