zoj 3524(拓扑排序+多重背包)(好题)

http://blog.csdn.net/woshi250hua/article/details/7824773

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define MAXN 1010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pqueue priority_queue
#define INF 0x3f3f3f3f

struct node
{
    int v,len;
}cur;

vector<node> mmap[705];

int n,m,w,x;

int tw[705],tv[705],cnt[705];

int st[705],result[705],flag[705];

long long dp[705][2005],power[705][2005],ans,dist;

void ptopo()
{
    for(int i =1;i<=n;i++) pf("%d ",result[i]);
    blank;
}

void Debug_InPut() {

    for (int i = 1; i <= n; ++i)
        for (int j = 0; j <= w; ++j)
            pf("(%lld %lld)%c",dp[i][j],power[i][j],j==w?‘\n‘:‘ ‘);
}

void init()
{
    ans = 0;
    dist = 0;
    memset(dp,0,sizeof(dp));
    memset(cnt,0,sizeof(cnt));
    memset(flag,0,sizeof(flag));
    memset(power,-1,sizeof(power));
    for(int i = 0; i <= n; ++i)
        mmap[i].clear();
}

void topo()
{
    int i,j;
    int tot = -1,index=0;
    for(i=1;i<=n;i++)
    {
        if(cnt[i]==0) st[++tot] = i;
        //pf("%d ",st[tot]);
    }
    //blank;
    while(tot>=0)
    {
        int xx = st[tot--];
        result[++index] = xx;
        int s = mmap[xx].size();
        //pf("tot%d\n",tot);
        for(j=0;j<s;j++)
        {
            cur = mmap[xx][j];
            int y = cur.v;
            //pf("xx%d y%d ",xx,y);
            cnt[y]--;
            if(cnt[y]==0)
            {
                st[++tot] = y;
                //pf("tot%d\n",tot);
                //pf("y%d ",y);
            }
        }
    }
    //ptopo();
}

void solve()
{
    int i,j,k;
    for(i=0;i<=w;i++)
    {
        power[x][i] = 0;
        if(i>=tw[x])
        {
            dp[x][i] = max(dp[x][i],dp[x][i-tw[x]]+tv[x]);
        }
        if (dp[x][i] > ans)
            ans = dp[x][i],dist = 0;
    }

    flag[x] = 1;
    for(i=1;i<=n;i++)
    {
        int xx = result[i];
        if(flag[xx]==0) continue;
        int s = mmap[xx].size();
        for(j=0;j<s;j++)
        {
            cur = mmap[xx][j];
            int tp = cur.v;
            flag[tp] = 1;
            for(k=0;k<=w;k++)
            {
                if(dp[tp][k] < dp[xx][k])
                {
                    dp[tp][k] = dp[xx][k];
                    power[tp][k] = power[xx][k] + cur.len*k;
                }
                else if(dp[tp][k] == dp[xx][k])
                {
                    if(power[tp][k] == -1)
                    {
                        power[tp][k] = power[xx][k]+cur.len * k;
                    }
                    else
                        power[tp][k] = min(power[xx][k] + cur.len*k ,power[tp][k]);
                }
            }

            for (k = tw[tp]; k <= w; ++k) {
                //完全背包
                if (dp[tp][k] < dp[tp][k-tw[tp]]+tv[tp]) {
                    dp[tp][k] = dp[tp][k-tw[tp]] + tv[tp];
                    power[tp][k] = power[tp][k-tw[tp]];
                }
                else if(dp[tp][k] == dp[tp][k-tw[tp]]+tv[tp])
                    power[tp][k] = min(power[tp][k],power[tp][k-tw[tp]]);
            }

            for (k = 0; k <= w; ++k) {
                //更新答案
                if (dp[tp][k] > ans)
                    ans = dp[tp][k],dist = power[tp][k];
                else if (dp[tp][k] == ans)
                    dist = min(dist,power[tp][k]);
            }
            //pf("cur %d:\n",cur.v),Debug_InPut();
        }
    }
}

int main()
{
    int i,j;
    while(~sf("%d%d%d%d",&n,&m,&w,&x))
    {
        init();

        for(i=1;i<=n;i++) sf("%d%d",&tw[i],&tv[i]);

        for(i=0;i<m;i++)
        {
            int x,y,l;
            sf("%d%d%d",&x,&y,&l);
            cur.v = y;
            cur.len = l;
            cnt[y]++;
            mmap[x].pb(cur);
        }
        topo();
        solve();
        //pf("ans %lld %lld\n",ans,dist);
        printf("%lld\n",dist);
    }
    return 0;
}
时间: 2024-11-05 20:36:04

zoj 3524(拓扑排序+多重背包)(好题)的相关文章

Crazy Shopping(拓扑排序+完全背包)

Crazy Shopping(拓扑排序+完全背包) Because of the 90th anniversary of the Coherent & Cute Patchouli (C.C.P), Kawashiro Nitori decides to buy a lot of rare things to celebrate. Kawashiro Nitori is a very shy kappa (a type of water sprite that live in rivers) a

nyoj 546——Divideing Jewels——————【dp、多重背包板子题】

Divideing Jewels 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 Mary and Rose own a collection of jewells. They want to split the collection among themselves so that both receive an equal share of the jewels. This would be easy if all the jewels had the same

ZOJ3524:Crazy Shopping(拓扑排序+完全背包)

Because of the 90th anniversary of the Coherent & Cute Patchouli (C.C.P), Kawashiro Nitori decides to buy a lot of rare things to celebrate. Kawashiro Nitori is a very shy kappa (a type of water sprite that live in rivers) and she lives on Youkai Mou

hdu 2844 Coins 多重背包模板题 ,二进制优化。据说是楼教主的男人八题之一

Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8052    Accepted Submission(s): 3291 Problem Description Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One

hdu 1811 Rank of Tetris 并查集+拓扑排序,,提高题

Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5672    Accepted Submission(s): 1616 Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想

ZOJ3524Crazy Shopping(完全背包+拓扑排序)经典

H - Crazy Shopping Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Description Because of the 90th anniversary of the Coherent & Cute Patchouli (C.C.P), Kawashiro Nitori decides to buy a lot of rare things

poj 2392 Space Elevator (多重背包)

Space Elevator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8110   Accepted: 3843 题目大意  :一群牛要上天  用一些石块堆塔  给出石块的种类  及其每个种类的数量 和该种石块能出现的最高高度  和每种石块的数量 求怎么摆放才能堆得最高 多重背包模板题.... 将所有石块排序  把高度低的放下面 #include<iostream> #include<cstdio>

HDU 2191 多重背包

悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 22865    Accepted Submission(s): 9661 Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市

多重背包之 HDU -1171Big Event in HDU &amp;HDU -2191悼念512汶川大地震遇难同胞——珍惜现在,感恩生活

这两道题都是多重背包的基础题,前面的安格题意是:给出每个物体的价值和物体的数量,如何分使得A,B所得价值最接近并且A的价值不能小于B,就类似于NYOJ上的那个邮票分你一半那个意思,只不过这里不是一个而是多个,所以多重背包 前一个题是将总和的一半当作背包的容量来求,代码如下 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 7 int dp[1