#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define N 1000005 #define INF 999999999 int head[N], vis[N], queue[N], dis[N], outqueue[N]; int n, index; struct Edge { int v, value, next; }edge[N]; void add_Edge(int u, int v, int val) { edge[index].next=head[u]; edge[index].v=v; edge[index].value=val; head[u]=index++; } void Spfa(int s) { int iq=0, front=0, i, top; memset(vis, 0, sizeof(vis)); memset(outqueue, 0, sizeof(outqueue)); for(i=1; i<=n; i++) dis[i]=INF; dis[s]=0; queue[iq++]=s; vis[s]=1; while(iq!=front) { top=queue[front]; front++; vis[top]=0; outqueue[top]++; if(outqueue[top]>n) return ; for(i=head[top]; i!=-1; i=edge[i].next) { if(dis[top]+edge[i].value<dis[edge[i].v]) { dis[edge[i].v]=dis[top]+edge[i].value; if(vis[edge[i].v]==0) { vis[edge[i].v]=1; queue[iq++]=edge[i].v; } } } } } int main() { int nn, a, b, c, i, maxn; while(scanf("%d", &n)!=EOF) { maxn=0, index=0; memset(head, -1, sizeof(head)); for(i=0; i<n; i++) { scanf("%d%d%d", &a, &b, &c); maxn=max(maxn, b); add_Edge(a-1, b, -1*c); } for(i=1; i<=maxn; i++) { add_Edge(i, i-1, 1); add_Edge(i-1, i, 0); } n=maxn; Spfa(0); printf("%d\n", -1*dis[maxn]); } return 0; }
題目連接:http://poj.org/problem?id=1201 ios
題目大意:有一個集合,給出n個關係,每組關係三個數a, b, c表明[a, b]區間最少c個數。求出集合中作少有多少個數字算法
解題思路:[差分約束] 1.咱們首先要轉化成差分約束的特徵形勢x-y<=z的形勢。 ide
2.咱們設ti表示i以前的區間有多少個數。那麼tb-t(a-1)>=c ---(變形)--->t(a-1)-tb<=-c; spa
因爲ti咱們有合理的意義,那麼0=<ti-t(i-1)<=1,即相鄰兩個數區間最多增長1個數 變形獲得:ti-t(i-1)<=1 t(i-1)-ti<=0 code
3.組合上面的條件,獲得差分約束系統。建圖 blog
4.用spfa算法求解最短路 get
5.因爲t(a-1)-tb<=-c,c加了負號, 所以得出的結果要從負數變爲整數string
代碼以下:io