bzoj2330: [SCOI2011]糖果(差分约束)

  差分约束裸题,a==b的话分别建a>=b a<=b的边就行。倒序加边不然会TLE是什么鬼

#include<iostream> 
#include<cstring>
#include<cstdlib>
#include<cstdio>
#define ll long long
using namespace std;
const int maxn=500010,inf=1e9;
struct poi{int too,pre,sum;}e[maxn];
int n,m,x,y,z,front,rear,tot;
ll dist[maxn],ans;
int h[maxn],v[maxn],last[maxn],tim[maxn];
bool flag;
void read(int &k)
{
    int f=1;k=0;char c=getchar();
    while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
    k*=f;
}
void add(int x,int y,int z){e[++tot].too=y;e[tot].sum=z;e[tot].pre=last[x];last[x]=tot;}
void spfa()
{
    for(int i=0;i<=n;i++)dist[i]=-inf;
    dist[0]=0;v[0]=1;front=rear=0;h[++rear]=0;
    while(front!=rear)
    {
        int now=h[++front];if(front==maxn)front=-1;
        for(int i=last[now],too=e[i].too;i;i=e[i].pre,too=e[i].too)
        if(dist[too]<dist[now]+e[i].sum)
        {
            dist[too]=dist[now]+e[i].sum;
            if(++tim[too]>2333){printf("-1");flag=1;return;}
            if(!v[too])
            {
                v[too]=1;h[++rear]=too;
                if(rear==maxn)rear=-1;
            }
        }
        v[now]=0;
    }
}
int main()
{
    read(n);read(m);
    for(int i=n;i;i--)add(0,i,1);
    for(int i=1;i<=m;i++)
    {
        read(z);read(x);read(y);
        if(z==1)add(x,y,0),add(y,x,0);
        if(z==2)
        {
            if(x==y){printf("-1");return 0;}
            add(x,y,1);
        }
        if(z==3)add(y,x,0);
        if(z==4)
        {
            if(x==y){printf("-1");return 0;}
            add(y,x,1);
        }
        if(z==5)add(x,y,0);
    }
    spfa();
    if(flag)return 0;
    for(int i=1;i<=n;i++)ans+=dist[i];
    printf("%lld
",ans);
    return 0;
}
View Code

 

原文地址:https://www.cnblogs.com/Sakits/p/7170937.html