http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1770
题意:参看图论200
分析:差分约束关键还是建图。嗨,图。而且差分约束感觉还有数学的思想。偶数学不好。
View Code
// I'm lanjiangzhou //C #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> #include <time.h> //C++ #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <cctype> #include <stack> #include <string> #include <list> #include <queue> #include <map> #include <vector> #include <deque> #include <set> using namespace std; //*************************OUTPUT************************* #ifdef WIN32 #define INT64 "%I64d" #define UINT64 "%I64u" #else #define INT64 "%lld" #define UINT64 "%llu" #endif //**************************CONSTANT*********************** #define INF 0x3f3f3f3f // aply for the memory of the stack //#pragma comment (linker, "/STACK:1024000000,1024000000") //end const int nmax = 1000+10; const int emax = 23000+100; int n;//一共有几个大营 int m;//已知从第i个大营到第j个大营至少有几个士兵,这些信息有m条 int c[nmax];//第i个大营最多有c[i]个士兵 int d[nmax];//d[0]=0; d[1]=c[1]; d[2]=c[1]+c[2]....即d[i]为前i个大营容量总和 int ei;//边的序号 int dis[nmax];//从源点到个顶点最短路径长度(注意:源点为sn而不是s0) struct eg{ int u,v,w;//边:起点,终点,权值 }edges[emax]; void init(){ ei=0; //除源点sn外,其他顶点的最短距离初始为inf //则bellman_ford算法的第一重要循环n-1次 for(int i=0;i<=n;i++) { dis[i]=INF; } dis[0]=0; dis[n]=0; //一下bellman_ford算法是以sn为源点的,所以dis[n]=0; } bool bellman_ford(){ //bellman_ford()算法的第一重循环要执行n-1次,n是网络中顶点的个数 //本题中顶点个数n+1; for(int i=0;i<n;i++){ //假设第k条边的起点是u,终点是v,以下循环考虑第k条边是否会使得源点v0到v的最短距离缩短, //即判断dis[edges[k].u]+edges[k].w<dis[edges[k].v]是否成立 for(int k=0;k<ei;k++){ int t=dis[edges[k].u]+edges[k].w; if(dis[edges[k].u]!=INF&&t<dis[edges[k].v]){ dis[edges[k].v]=t; } } } //以下是检查,若还有更新则说明存在无限循环的负值回路 for(int k=0;k<ei;k++){ if(dis[edges[k].u]!=INF&&dis[edges[k].u]+edges[k].w<dis[edges[k].v]){ return false; } } return true; } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ init(); int u,v,w; //构造不等式组(3)和(4) for(int i=1;i<=n;i++){ scanf("%d",&c[i]);//读入第i个兵营最多有ci个士兵 edges[ei].u=i-1; edges[ei].v=i; edges[ei].w=c[i];//构造<i-1,i>,权值为ci; ei++; edges[ei].u=i; edges[ei].v=i-1; edges[ei].w=0; //构造边<i,i-1>,权值为0 ei++; d[i]=c[i]+d[i-1]; } //构造不等式组(1)和(2) for(int i=0;i<m;i++){ scanf("%d%d%d",&u,&v,&w); edges[ei].u=v; edges[ei].v=u-1; edges[ei].w=-w;//构造边<v,u-1> 权值为-w; ei++; } if(!bellman_ford()) printf("Bad Estimations\n"); else printf("%d\n",dis[n]-dis[0]); } return 0; }