差分约束
poj3159
题意:n个人,m个信息,每行的信息是3个数字,A,B,C,表示B比A多出来的糖果不超过C个,问你,n号人最多比1号人多几个糖果
思路:对应最短路模型,在松弛完最短路后则变为 d[v] <= d[u] + w ,转化为 d[v] - d[u] <= w,这个和上面的 B - A <= C 是相同的模式 , 因此建图的时候A和B连一条有向边 , 边权为C,以1为起点,n为终点跑一遍最短路即可
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxn=150010; const int INF=0x3f3f3f3f; int head[maxn]; bool vis[maxn]; int Q[maxn];//堆栈 int dist[maxn]; int n,m; int a,b,c,tol; struct Edge { int to; int v; int next; }edge[maxn]; void addedge(int a,int b,int v) { edge[tol].to=b; edge[tol].v=v; edge[tol].next=head[a]; head[a]=tol++; } void SPFA(int start,int n) { int top=0; for(int v=1;v<=n;v++) { if(v==start) { Q[top++]=v; vis[v]=true; dist[v]=0; } else { vis[v]=false; dist[v]=INF; } } while(top!=0) { int u=Q[--top]; vis[u]=false; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(dist[v]>dist[u]+edge[i].v) { dist[v]=dist[u]+edge[i].v; if(!vis[v]) { vis[v]=true; Q[top++]=v; } } } } } int main() { memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); tol=0; while(m--) { scanf("%d%d%d",&a,&b,&c); addedge(a,b,c); } SPFA(1,n); printf("%d\n",dist[n]); return 0; }
poj3169
一共有n头牛,有ml个关系好的牛的信息,有md个关系不好的牛的信息,对应输入的第一行的三个元素,接下来ml行,每行三个元素A,B,D,表示A牛和B牛相距不希望超过D,接下来md行,每行三个元素A,B,D表示A牛和B牛的相距至少要有D才行。求1号牛和n号牛的最大距离,如果距离无限大输出-2,如果无解输出-1。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxn=20020; const int INF=0x3f3f3f3f; int head[maxn]; bool vis[maxn]; int cnt[maxn]; int Q[maxn];//堆栈 int dist[maxn]; int n,m,ml; int a,b,c,tol; struct Edge { int to; int v; int next; }edge[maxn]; void addedge(int a,int b,int v) { edge[tol].to=b; edge[tol].v=v; edge[tol].next=head[a]; head[a]=tol++; } bool SPFA(int start,int n) { int rear=0,frot=0; for(int v=1;v<=n;v++) { if(v==start) { Q[rear++]=v; vis[v]=true; cnt[v]=1; dist[v]=0; } else { vis[v]=false; dist[v]=INF; cnt[v]=0; } } while(rear!=frot) { int u=Q[frot++]; vis[u]=false; if(frot>=maxn) frot=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(dist[v]>dist[u]+edge[i].v) { dist[v]=dist[u]+edge[i].v; if(!vis[v]) { vis[v]=true; Q[rear++]=v; if(rear>=maxn) rear=0; if(++cnt[v]>n) return false; } } } } return true; } int main() { memset(head,-1,sizeof(head)); while(~scanf("%d%d%d",&n,&m,&ml)) { tol=0; while(m--) { scanf("%d%d%d",&a,&b,&c); if(a>b)swap(a,b); addedge(a,b,c); } while(ml--) { scanf("%d%d%d",&a,&b,&c); if(a<b) swap(a,b); addedge(a,b,-c); } if(!SPFA(1,n)) printf("-1\n"); else if(dist[n]==INF) printf("-2\n"); else printf("%d\n",dist[n]); } return 0; }