依赖01背包+差分约束
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了依赖01背包+差分约束相关的知识,希望对你有一定的参考价值。
P1260 工程规划
引入超级源点,得到每个任务最大能满足的要求
用各个任务减去这个最小值,就是各个工程开始的时间。
无解的情况:spfa中每个点别松弛n-1次,如果有点被松弛了n次,则无解。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
int n,m,head[maxn],cnt,dist[maxn],num[maxn];
bool vis[maxn];
struct node
int to,nxt,dis;
e[maxn];
void add(int u,int v,int w)
e[++cnt].to=v;
e[cnt].dis=w;
e[cnt].nxt=head[u];
head[u]=cnt;
queue<int>q;
bool spfa(int u)
memset(dist,inf,sizeof(dist));
dist[u]=0;
q.push(u);
vis[u]=1;
num[u]++;
while(!q.empty())
int u=q.front();q.pop();
vis[u]=0;
for(int i=head[u];i;i=e[i].nxt)
int v=e[i].to;
if(dist[v]>dist[u]+e[i].dis)
dist[v]=dist[u]+e[i].dis;
if(!vis[v])
num[v]++;
q.push(v);
vis[v]=1;
if(num[v]==n)
return 0;
return 1;
signed main()
scanf("%lld%lld",&n,&m);
for(int i=1;i<=m;i++)
int u,v,w;scanf("%lld%lld%lld",&u,&v,&w);
add(v,u,w);
for(int i=1;i<=n;i++)
add(n+1,i,0);
int mi=inf;
if(spfa(n+1))
for(int i=1;i<=n;i++)
mi=min(mi,dist[i]);
for(int i=1;i<=n;i++)
cout<<dist[i]-mi<<endl;
else
cout<<"NO SOLUTION"<<endl;
return 0;
有依赖的 01背包
思路:选了主件,就必须选附件。
因此在对每个主件做01背包时,再分别对附件做,取得最大值。
将附件存在主件的后面,另开一个数组存取。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n,m,v[maxn],w[maxn],p[maxn][3],q[maxn][3],f[maxn];
int main()
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
int a,b,c;cin>>a>>b>>c;
if(!c)
v[i]=a;w[i]=a*b;
else
p[c][0]++;
p[c][p[c][0]]=a;
q[c][p[c][0]]=a*b;
for(int i=1;i<=m;i++)
for(int j=n;j>=v[i];j--)
f[j]=max(f[j],f[j-v[i]]+w[i]);
if(j>=v[i]+p[i][1])
f[j]=max(f[j],f[j-v[i]-p[i][1]]+w[i]+q[i][1]);
if(j>=v[i]+p[i][2])
f[j]=max(f[j],f[j-v[i]-p[i][2]]+w[i]+q[i][2]);
if(j>=v[i]+p[i][1]+p[i][2])
f[j]=max(f[j],f[j-v[i]-p[i][1]-p[i][2]]+w[i]+q[i][1]+q[i][2]);
cout<<f[n]<<endl;
return 0;
以上是关于依赖01背包+差分约束的主要内容,如果未能解决你的问题,请参考以下文章