首页 > 代码库 > hdu3666 THE MATRIX PROBLEM --- 差分约束

hdu3666 THE MATRIX PROBLEM --- 差分约束

这要是碰上现场赛我得被搞死 从RE到TLE到WA已疯。。


这题建图没有那么直接,通过给出的不等式关系一时想不到怎么建图

所以要对题目给的条件一定程度化简,将不等式两边取对数化简得到Sa-Sb<=c的形式

要注意w取double类型

其次,这题卡时间,根据经验加剪枝:

1、出队次数>sqrt(n)则判断有负环

2、统计总的入队次数,>2n则判断有负环

一般情况下不用这个,因为不严谨


下面两个spfa都是对的,手写队列稍快一点,上面第二个剪枝效果明显

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;

struct node
{
    int v;
    double w;
    int next;
}e[360010];
int n,m,h,head[810],inq[810],outq[810],q[50000];
double d[805];

void addedge(int a,int b,double c)
{
    e[h].v=b;
    e[h].w=c;
    e[h].next=head[a];
    head[a]=h++;
}

bool spfa(int s)
{
    int iq,i,top,k;
    for(i=0;i<=n;i++)
        d[i]=1000000000;
    memset(inq,0,sizeof inq);
    memset(outq,0,sizeof outq);
    d[s]=0;inq[s]=1;
    iq=0;i=0;
    q[iq++]=s;
    while(i!=iq)
    {
        top=q[i];
        inq[top]=0;
        outq[top]++;
        if(outq[top]>(int)sqrt(n*1.0)) return 0;
        k=head[top];
        while(k>=0)
        {
            if(d[e[k].v]-e[k].w>d[top])
            {
                d[e[k].v]=e[k].w+d[top];
                if(!inq[e[k].v])
                {
                    inq[e[k].v]=1;
                    q[iq++]=e[k].v;
                }
            }
            k=e[k].next;
        }
        i++;
    }
    return 1;
}

int spfa(int st)//邻接表 STL
{
    for(int i=0;i<=n;i++)
        d[i]=100000000;
    memset(inq,0,sizeof inq);
    memset(outq,0,sizeof outq);
    d[st]=0;inq[st]=1;
    queue<int> q;
    q.push(st);
    int cnt=1;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        inq[x]=0;
        outq[x]++;
        if(outq[x]>sqrt(n*1.0)+10) return 0;
        for(int i=head[x];i!=-1;i=e[i].next)
        {
            if(d[e[i].v]>d[x]+e[i].w)
            {
                d[e[i].v]=d[x]+e[i].w;
                if(!inq[e[i].v])
                {
                    cnt++;
                    if(cnt>((n+m)*2)) return 0;
                    inq[e[i].v]=1;
                    q.push(e[i].v);
                }
            }
        }
    }
    return 1;
}

int main()
{
    double x,ll,uu,l,u;
    int i,j;
    while(~scanf("%d%d%lf%lf",&n,&m,&l,&u))
    {
        memset(head,-1,sizeof head);
        h=0;
        ll=log(l);uu=log(u);
        for(i=0;i<n;i++)
            for(j=0;j<m;j++)
            {
                scanf("%lf",&x);
                addedge(i,j+n,log(x)-ll);
                addedge(j+n,i,uu-log(x));
            }
        n+=m;m+=m;
        if(spfa(0)) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}