標籤:spfa 差分約束
差分約束(最短路)
不等式用最短路來求。問題是好難找約束條件——建立不等式。
題意問最少有多少兵。即建立好各點的約束條件,求0~N 的最短路。
有負環得判斷入隊次數。
反正還沒多大理解差分約束,Hurry up!
#include<cstdio>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<stack>#include<iostream>#include<list>#include<set>#include<cmath>#define INF 0x7fffffff#define eps 1e-6#define LL long longusing namespace std;int n,m;int d[1001];struct lx{ int v,len;};vector <lx> g[1001];int SPFA(){ queue<int>q; int dis[1001]; bool vis[1001]; int que[1001]; for(int i=0;i<=n;i++) dis[i]=INF,que[i]=vis[i]=0; q.push(0); vis[0]=1,dis[0]=0; while(!q.empty()) { int u=q.front();q.pop(); vis[u]=0,que[u]++; if(que[u]>n)return 1; for(int j=0;j<g[u].size();j++) { int v=g[u][j].v; int len=g[u][j].len; if(dis[v]>dis[u]+len) { dis[v]=dis[u]+len; if(!vis[v]) { vis[v]=1; q.push(v); } } } } return dis[n];}int main(){ while(scanf("%d%d",&n,&m)!=EOF) { int u,v,len; for(int i=0;i<=n;i++) g[i].clear(); d[0]=0; lx now; for(int i=1; i<=n; i++) { scanf("%d",&d[i]); now.v=i-1,now.len=d[i]; g[i].push_back(now); now.v=i,now.len=0; g[i-1].push_back(now); d[i]=d[i-1]+d[i]; } while(m--) { scanf("%d%d%d",&u,&v,&len); now.v=v,now.len=-len; g[u-1].push_back(now); now.v=u-1,now.len=d[v]-d[u-1]; g[v].push_back(now); }// for(int i=0;i<=n;i++)// {// printf("%d -> ",i);// for(int j=0;j<g[i].size();j++)// printf("%d:%d ",g[i][j].v,g[i][j].len);// printf("\n");// } int tmp=SPFA(); if(tmp==1) puts("Bad Estimations"); else printf("%d\n",-tmp); }}
ZOJ 2770 Burn the Linked Camp