Source: Internet
Author: User

Crazy Shopping (topological sort + full backpack)

Because of the 90th anniversary of the *coherent & Cute patchouli* (C.C.P), *Kawashiro Nitori* decides t o buy a lot of rare things to celebrate.

*Kawashiro Nitori* is a very shy *kappa* (a type of water sprite this live in rivers) and she lives on *Y Oukai Mountain*. *Youkai Mountain* is a dangerous place full of *Youkai*, so normally humans was unable to being close to the MO Untain. But because of the financial crisis, something has changed. For example, *Youkai Mountain* becomes available for tourists.

On the mountain there are N tourist attractions, and there are a shop in each tourist attraction. T O make the tourists feel more challenging (for example, to collect all kinds of souvenirs), each shop sells only one speci Fic kind of souvenir that can is not buy in any other shops. Meanwhile, the number of the souvenirs which sells is infinite. * Nitori * also knows the EAC H kind of souvenir has a weight , TWi (in kilogram) and a value TVi .

now * Nitori * is ready to buy souvenirs. For convenience, , * Nitori * numbered The tourist attraction from 1 to N . At the beginning , * Nitori * is located at the tourist attraction X and there are& nbsp M roads Connect some pairs of tourist attractions, and each road have a length L . However, because * Youkai Mountain * is very steep, all roads is uni-directional. By the the-the-same strange reason, the roads ensure that when someone left one tourist attraction, he can not arrive at The same tourist attraction again if he goes along the road.

*Nitori* have one bag and the maximal load is W kilogram. When there K is kilogram things in *Nitori*'s bag, she needs to cost units energy for K walking one unit l Ength Road. Of course she doesn ' t want to waste too much energy, so please calculate the minimal cost of energy of *Nitori* whe n the value is maximal.

Notice: *Nitori* can buy souvenir at tourist attraction X , and she can stop at any tourist attraction. Also, there is no, different roads between the same, tourist attractions. Moreover, though the shop sells different souvenirs, it's still possible for the different kinds of souvenir has the SAM e weight or value.

There is multiple test cases. For each test case:

The first line contains four numbers N (1 <= N <=)-The number of tourist attractions, M (1 <= c3/> <= 60000)-The number of roads, W (1 <= W <=)-The load of the bag and X (1 <= X & lt;= N )-The starting point of*Nitori*.

Then followed N by lines, each line contains the integers which means the shop on tourist attraction i sells the TWi TVi and Things (1 <= TWi <= W, 1 <= TVi <= 10000).

Next, there is M lines, each line contains three numbers, Xi , Yi and Li , which means there is a one-way road From tourist attraction Xi to Yi , and the length is Li (1 <= Xi , Yi <= N, 1 <= Li <= 10000).

OutputFor each test case, output the answer as the description required.

Sample InputSample Output4 4 10 11 12 33 44 51 2 51 3 42 4 43 4 5

0

Title Link: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4439

The main topic: there used to be N mountain, there is a temple in the mountain, there is an old monk in the temple, the old monk specially sends the souvenir, each souvenir weight is cost[i], the value is val[i]. N-Mount Mountain form a map with M-Edge, a mountain hill has a distance dist[i]. Lead xx from St Point, carrying a capacity of M backpack, want to collect the most value. But the protagonist sickly to take care of the body, each carrying the weight of wi from a mountain to a certain mountain will consume Dist[i]*wi energy. What is the minimum amount of energy consumed at the end of the maximum value?

Problem-solving ideas: Looks like a divine question, but careful analysis is a topological sort + full backpack, but the details are a bit of egg pain. I initially wanted to do a complete backpack for each point first, so the transfer would be just as good. But it seems difficult to achieve this.

Set DP[I][J] to reach the maximum value of J in the I-point backpack, power[i][j] represents the minimum cost when the value is greatest. According to the beginning of a paragraph said the transfer, then DP[I][J] will be updated, this time power[i][j] should be 0, because do not know the front ran tens of thousands of thousands of. But this is not reliable, first not to say from St can to I, say can arrive, how do we get a and dp[i][j] the same value, then power should be updated to how much? and Dp[i][j] How to update?

This is my attempt at a failure, but the subsequent analysis is also helpful, I just need to sort the topology first, then use the topological sequence to move backward, transfer to the next point to do a full backpack, a point may be transferred from a lot of songs, priority update Dp[i][j] and then update power[i][j], The transferred dp[i][j] and Power[i][j] are all from the former order node, if. The next node must be flagged for each transfer, indicating whether it can come from the St point.

The specific transfer equation is very much like a full backpack, just as the value of the transfer is based on power, the implementation of the Code.

Test data:

4 4 10 1

1 1

2 3

3 4

4 5

1 2 5

1 3 4

2 4 4

3 4 5

4 4 10 1

3 5

2 2

3 3

1 1

1 2 5

1 3 10

2 4 4

3 4 5

4 4 15 1

4 7

2 3

3 3

1 1

1 2 5

1 3 10

2 4 0

3 4 5

4 4 0 1

4 7

2 3

3 3

1 1

1 2 5

1 3 10

2 4 0

3 4 5

4 4 15 4

4 7

2 3

3 3

1 1

1 2 5

1 3 10

2 4 0

3 4 5

4 4 15 2

4 7

2 3

3 3

1 1

1 2 5

1 3 10

2 4 0

3 4 5

4 3 15 1

2 3

3 3

2 1

1 1

1 3 0

2 3 5

3 4 0

4 3 15 1

2 3

3 3

2 1

1 1

1 3 0

2 3 5

3 4 10

Output:

15 0

16 81

25 60

0 0

15 0

22 0

22 0

22 140

#include <cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<vector>using namespacestd;#defineMIN 710#defineMAX 2100#defineMem (a,x) memset ((a), (x), sizeof ((a)))intn,m,road,x;intCost[min],val[min],flag[min];intSt[min],top,cnt[min],real[min],index;intdp[min][max],power[min][max],ans,dist;structnode{intV,len;} Cur;vector<node>Mmap[min];voidTuopu () { for(intI=1; i<=n; i++) { if(cnt[i]==0) st[++top]=i; while(top!=0) { intv=st[top--]; real[++index]=v; intSize =mmap[v].size (); for(intj=0; j<size; J + +) {cur=Mmap[v][j]; CNT[CUR.V]--; if(cnt[cur.v]==0) st[++top]=CUR.V; } } }}voidSolve_ac () {intI,J,K,S,V,SIZE,TP; for(j =0; J <= M; ++j) {//equivalent to initializePOWER[X][J] =0; if(J >=cost[x]) dp[x][j]= Max (dp[x][j],dp[x][j-cost[x]]+val[x]); if(Dp[x][j] >ans) ans= Dp[x][j],dist =0; //printf ("%d%lld ans%lld\n", J,dp[x][j],ans);} Flag[x]=1; for(i =1; I <= N; ++i) {v=Real[i]; if(Flag[v] = =0)Continue;//flag is 0, which means it cannot be reachedSize =mmap[v].size (); for(s =0; s < size; ++s) {cur=Mmap[v][s]; TP= CUR.V,FLAG[TP] =1;//up to, TP is the next node number for(j =0; J <= M; ++j) {if(Dp[tp][j] < dp[v][j])//priority to be transferred according to DP[TP][J]{Dp[tp][j]=Dp[v][j]; POWER[TP][J]= Power[v][j] + Cur.len *J; } Else if(Dp[tp][j] = = Dp[v][j])//when Dp[tp][j] and dp[v][j] are equal, they are transferred according to Power[i][j] . { if(Power[tp][j] = =-1)//first time to reach TP pointPOWER[TP][J] = Power[v][j]+cur.len *J; ElsePower[tp][j]= Min (Power[tp][j],power[v][j] + Cur.len *j); } //without this, there will be more costs behind than before, but the actual value is the same if(j && dp[tp][j] = = dp[tp][j-1]) Power[tp][j]= Min (power[tp][j],power[tp][j-1]); } for(j = cost[tp]; j <= m; + +j) {//Full Backpack if(Dp[tp][j] < dp[tp][j-cost[tp]]+VAL[TP]) {Dp[tp][j]= DP[TP][J-COST[TP]] +VAL[TP]; POWER[TP][J]= power[tp][j-COST[TP]]; } Else if(Dp[tp][j] = = dp[tp][j-cost[tp]]+VAL[TP]) power[tp][j]= Min (power[tp][j],power[tp][j-COST[TP]]); } for(j =0; J <= M; ++j) {//Update Answer if(Dp[tp][j] >ans) ans= Dp[tp][j],dist =Power[tp][j]; Else if(Dp[tp][j] = =ans) Dist=min (dist,power[tp][j]); } //printf ("cur%d:\n", cur.v), Debug_input (); } }}intMain () {intI,j,k,a,b,c; while(SCANF ("%d%d%d%d", &n,&road,&m,&x)! =EOF) {Index=0; Top=ans=dist=0; MEM (DP,0); MEM (CNT,0); MEM (Flag,0); Mem (Power,-1); for(i=0; i<=n; i++) {mmap[i].clear (); } for(i=1; i<=n; i++) {scanf ("%d%d",&cost[i],&Val[i]); } for(i=1; I<=road; i++) {scanf ("%d%d%d",&a,&b,&c); CNT[B]++; CUR.V=b; Cur.len=B; Mmap[a].push_back (cur); } tuopu (); Solve_ac (); printf ("%d\n", Dist); } return 0;}View Code

"In the original reproduced"

Crazy Shopping (topological sort + full backpack)

Related Article