依赖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背包+差分约束的主要内容,如果未能解决你的问题,请参考以下文章

差分约束系统

HDU3592差分约束

P3275 [SCOI2011]糖果 && 差分约束

洛谷 P5960 模板差分约束算法(spfa)

Gym - 101002D:Programming Team (01分数规划+树上依赖背包)

01背包问题-动态规划算法