bzoj 1731 [Usaco2005 dec]Layout 排队布局——差分约束

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1731

对差分约束理解更深。还发现美妙博客:http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html

原来不是一定要有一个源点向每个点连0边。而且“不可到达”原来是那个意思。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
const int N=1005,M=2e4+5+N;
int n,ml,md,hd[N],xnt,to[M],nxt[M],w[M],cnt[N];
ll dis[N];
bool vis[N];
queue<int> q;
int rdn()
{
    int ret=0;bool fx=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
    while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
    return fx?ret:-ret;
}
void add(int x,int y,int z)
{
    to[++xnt]=y; nxt[xnt]=hd[x]; hd[x]=xnt; w[xnt]=z;
}
ll spfa()
{
    memset(dis,0x3f,sizeof dis); dis[1]=0; cnt[1]=1;
    q.push(1); vis[1]=1;  ll INF=dis[2];
    while(q.size())
    {
        int k=q.front(); q.pop(); vis[k]=0;
        for(int i=hd[k],v;i;i=nxt[i])
            if(dis[v=to[i]]>dis[k]+w[i])
            {
                dis[v]=dis[k]+w[i];
                if(!vis[v])
                {
                    q.push(v);cnt[v]++;
                    if(cnt[v]==n) return -1;
                }
            }
    }
    return dis[n]==INF?-2:dis[n];
}
int main()
{
    n=rdn(); ml=rdn(); md=rdn();
    for(int i=1,u,v,z;i<=ml;i++)
    {
        u=rdn(); v=rdn(); z=rdn();
        add(u,v,z);
    }
    for(int i=1,u,v,z;i<=md;i++)
    {
        u=rdn(); v=rdn(); z=rdn();
        add(v,u,-z);
    }
    for(int i=2;i<=n;i++) add(i,i-1,0);
    printf("%lld\n",spfa());
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Narh/p/9704776.html