bzoj1731 [Usaco2005 dec]Layout 排队布局(差分约束+spfa)

这题我觉得应该先判有没有负环啊。。。如果1和n不连通,我们从1开始做spfa,如果n在一个负环中呢?我们就判断不到这个负环了啊。。我们会输出-2,可是我觉得应该是-1,根本不存在合法方案啊。。。迷。我先用dfs判负环的程序在bzoj上跑了2900+ms,可怕。。不判的话才20ms。。
不过话说dfs版spfa判负环也不会慢这么多啊。。待我研究下。

#include 
#include 
#include 
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
#define N 1010
#define M 20010
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int n,m1,m2,h[N],num=0,d[N],cnt[N];
bool inq[N];
struct edge{
    int to,next,val;
}data[M+N];
inline void add(int x,int y,int val){
    data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].val=val;
}
bool dfs(int x){
    inq[x]=1;
    for(int i=h[x];i;i=data[i].next){
        int y=data[i].to;
        if(d[y]>d[x]+data[i].val){
            d[y]=d[x]+data[i].val;if(inq[y]||!dfs(y)) return 0;
        }
    }inq[x]=0;return 1;
}
bool spfa(){
    queue<int>q;memset(d,inf,sizeof(d));
    d[1]=0;q.push(1);inq[1]=1;cnt[1]++;
    while(!q.empty()){
        int x=q.front();q.pop();inq[x]=0;
        for(int i=h[x];i;i=data[i].next){
            int y=data[i].to;
            if(d[y]>d[x]+data[i].val){
                d[y]=d[x]+data[i].val;if(++cnt[y]>n) return 0;
                if(!inq[y]) inq[y]=1,q.push(y);
            }
        }
    }return 1;
}
int main(){
//  freopen("a.in","r",stdin);
    n=read();m1=read();m2=read();
    while(m1--){
        int x=read(),y=read(),val=read();add(x,y,val);
    }
    while(m2--){
        int x=read(),y=read(),val=read();add(y,x,-val);
    }for(int i=1;i1,i,0);
//  memset(d,0,sizeof(d));
//  for(int i=1;i<=n;++i) if(!dfs(i)){puts("-1");return 0;}//判负环 
    if(!spfa()){puts("-1");return 0;};
    if(d[n]==inf){puts("-2");return 0;}
    printf("%d\n",d[n]);
    return 0;
}

你可能感兴趣的:(bzoj,差分约束,最短路)