礼物分配
10.11
思路:
直接前缀和,各种限制可以转化为dis[u]-dis[v]<=c的形式,然后直接跑差分约束即可。因为是求满足所有条件的最小值,那么就是按照限制建边后跑最长路。
具体细节看代码。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#define LL long long
#define N 1010
using namespace std;
int n, m, idc;
int head[N];
int vis[N], dis[N];
bool flag;
struct Edge{
int to, nxt, w;
}ed[N * 20];
void adde(int u, int v, int w){
ed[++idc].to = v;
ed[idc].nxt = head[u];
ed[idc].w = w;
head[u] = idc;
}
queue <int> q;
void spfa(int u){
memset(dis, -127, sizeof(dis));
memset(vis, 0, sizeof(vis));
q.push(u);
vis[u] = 1; dis[u] = 0;
while( !q.empty() ){
u = q.front(); q.pop();
for(int i=head[u]; i; i=ed[i].nxt){
int v = ed[i].to;
if(dis[v] < dis[u] + ed[i].w){
dis[v] = dis[u] + ed[i].w;
if( !vis[v] ){
q.push( v );
vis[v] = 1;
}
}
}
vis[u] = 0;
}
}
int main(){
freopen ("a.in", "r", stdin);
freopen ("a.out", "w", stdout);
scanf("%d%d", &n, &m);
for(int i=1; i<=m ;i++){
int l, r, c; scanf("%d%d%d", &l, &r, &c);
adde(l-1, r, c);
}
for(int i=0; i<n; i++){
adde(i, i+1, 0); adde(i+1, i, -1);
}
spfa( 0 );
cout << dis[n] << endl;
}