POJ3169 差分约束系统(+SPFA)

    xiaoxiao2021-03-25  62

    大意: n头牛编号为1到n,按照编号的顺序排成一列,每两头牛的之间的距离 >= 0。这些牛的距离存在着一些约束关系:1.有ml组(u, v, w)的约束关系,表示牛[u]和牛[v]之间的距离必须 <= w。2.有md组(u, v, w)的约束关系,表示牛[u]和牛[v]之间的距离必须 >= w。问如果这n头无法排成队伍,则输出-1,如果牛[1]和牛[n]的距离可以无限远,则输出-2,否则则输出牛[1]和牛[n]之间的最大距离。

    我们假设(u)<(v)。 对u,v做ml处理时,题目有dis[v]-dis[u]<=w; 即dis[u]+w>=dis[v],所以这里要从u到v建一条长度为w的边。

    对u,v做md处理时,题目有dis[v]-dis[u]>=w; 即dis[v]+(-w)>=dis[u],所以这里要从v到u建一条长度为-w的边。

    然后求最短路即可。

    特殊情况: 负环存在时取最小值会导致一个点必须要在自己前面,但那是不可能的事(输出-1)。 当dis[n]没有改变时说明1和n没有联系,即可以无穷大(输出-2)。

    我的代码比较凌乱,不是很方便看懂。 (不是很理解我即便很浪费空间也不至于多花别人十几倍啊)

    /* memory:4088k time:32ms */ #include<cstdio> #include<cstring> using namespace std; #define N 1010 int n,ml,md,w[N][N]; int dis[N],cnt[N],que[N]; bool in[N]; inline void uni(int x) { int a,b,dis; scanf("%d%d%d",&a,&b,&dis); if((a>b)^(x==-1)) a^=b^=a^=b; w[a][b]=dis*x; } int spfa() { int hd=1,tl=1; que[hd]=1; dis[1]=0; while(hd<=tl) { int x=que[hd++%N]; in[x]=0; for(int i=1; i<=n; i++) { int len=dis[x]+w[x][i]; if(w[x][i]&&len<dis[i]) { dis[i]=len; if(!in[i]) { in[i]=1; que[++tl%N]=i; if(++cnt[i]>=n) return -1; } } } } if(dis[n]==522133279) return -2; return dis[n]; } int main() { memset(dis,31,sizeof(dis));//522133279 scanf("%d%d%d",&n,&ml,&md); while(ml--) uni(1); while(md--) uni(-1); printf("%d",spfa()); }
    转载请注明原文地址: https://ju.6miu.com/read-36615.html

    最新回复(0)