zoj 2770 Burn the Linked Camp

 

差分约束第一题。

 

这个是我这两天对差分约束的理解,http://blog.csdn.net/zxy_snow/archive/2011/02/06/6173375.aspx

 

这个题见http://www.cnblogs.com/sysuwhj/archive/2011/01/26/1945786.html

 

 

设x[i] 为第i个营的人数,s[i] = x[1] + x[2] + … + x[i], s[0] = 0

则对于题目

Ci 有: 0 <= s[i] – s[i-1] <= Ci

i, j, k有: s[j] – s[i-1] >= k

还有: s[i] >= 0 (1 <= i <= n) , 即 s[i] – s[0] >= 0

这题求最小值,以0为源点求最长路

 

代码是按小于等于建的图,求最小值,用SPFA求最长路即可。

 

 

判断是否有环(这个是正环)。(如果入队次数大于节点数,说明有环)

 

#include <cstdio> #include <cstdlib> #include <iostream> #include <string.h> #include <queue> #include <limits.h> #define MAX 1010 using namespace std; typedef struct MAP{ int to,len; MAP *next; }MAP; MAP *map[MAX],node[MAX*100]; int cou; int n,m; void init() { memset(map,'/0',sizeof(map)); memset(node,'/0',sizeof(node)); cou = 0; } void Add(int u,int v,int len) { node[cou].to = v; node[cou].len = len; node[cou].next = map[u]; map[u] = &node[cou++]; } int SPFA() { queue<int> Q; MAP *head; int i,inq[MAX],dis[MAX],time[MAX],x,len,to; for(i=0; i<=n; i++) dis[i] = INT_MIN; memset(inq,0,sizeof(inq)); memset(time,0,sizeof(time)); Q.push(0); inq[0] = time[0] = 1; dis[0] = 0; while( !Q.empty() ) { x = Q.front(); Q.pop(); inq[x] = 0; head = map[x]; while( head != NULL ) { to = head->to; len = head->len; if( dis[to] < dis[x] + len ) { dis[to] = dis[x] + len; if( !inq[to] ) { Q.push(to); time[to]++; inq[to] = 1; if( time[x] > n ) return -1; } } head = head->next; } } return dis[n]; } int main() { int i,from,to,x,len,ans; while( scanf("%d%d",&n,&m) != EOF ) { init(); for(i=1; i<=n; i++) { scanf("%d",&x); Add(i-1,i,0); Add(i,i-1,-x); } for(i=1; i<=m; i++) { scanf("%d%d%d",&from,&to,&len); Add(from-1,to,len); } ans = SPFA(); if( ans != -1 ) printf("%d/n",ans); else printf("Bad Estimations/n"); } return 0; }  

你可能感兴趣的:(struct,null)