鏈接:https://ac.nowcoder.com/acm/problem/14970
來源:牛客網
題目描述
馬雲:“哈哈,女生的錢最好賺了!”
疊紙:“馬雲說得對!”
騰訊:“哇!真的耶!求代理!”
小P眼一眯,嘴角一挑,似乎發現了商機。不就是抽卡過關看CG麼,我也能做啊!於是乎,一個月後,一款《戀與程序員》誕生了。
遊戲裏設置了n個事件,m個關卡,k張卡片。每一個事件都有一張獨一無二的CG,但是每個關卡,都需要擁有特定的卡片才能通關。從一個事件,觸發另一個事件,需要通過一個特定的關卡。我們給事件編號爲1~n,對應的CG編號與事件的編號一致。卡片編號爲1~k。一開始,玩家會觸發事件1,並拿到1號CG,但是從此之後,玩家如果想觸發別的事件,便要通過闖關來達到。
現在,小Q想要c號CG(觸發c號事件獲得),但是小Q卻又不想花太多的錢。於是小Q查了攻略,以事件爲點,關卡爲邊,作了一張圖,並且小Q知道每個關卡都需要什麼卡片以及卡片的售價。請你計算一下,小Q拿到c號CG,至少要花多少錢。
注意,過關並不需要消耗卡片,同一張卡片可以通關多次。
輸入描述:
數據有多組,處理到文件結束。
每組數據第一行有四個整數n,m,k,c,代表事件數量、關卡數量、卡片數量以及小Q想要的CG的編號。
接下來m行,每行三個整數u,v,e,代表從u號事件可以通過闖關觸發v號事件,並且需要e號卡片。
接下來k行,每行兩個整數a,b,代表a號卡片的售價是b。
輸出描述:
每組數據輸出一行,一個整數,代表小Q拿到c號CG的最小花費。
示例1
輸入
6 7 5 6
2 3 2
4 3 3
1 2 1
1 5 4
4 6 5
1 4 2
5 6 3
1 100
3 422
2 210
5 107
4 38
輸出
317
備註:
對於100%的數據,
1 <= n,m,k <= 100;
1 <= u,v <= n;
1 <= a,c,e <= k;
1 <= b <= 1000。
#include <iostream>
#include<stdio.h>
#include<string.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=113;
int map[maxn][maxn],dis[maxn],value[maxn],book[maxn],visted[maxn];
int n,m,k,c,ans=0,tmp=0;
void first()
{
mem(map,0);
mem(value,0);
//mem(book,0);
mem(visted,0);
}
int chang(int t)
{
return value[t];
}
void dfs(int rt,int pre)
{
if(rt==c)
{
ans=min(ans,tmp);
return ;
}
for(int i=1;i<=n;i++){
int t=map[rt][i];
if(visted[t]==0&&pre!=i&&t){
tmp+=chang(t);
visted[t]=1;
dfs(i,rt);
visted[t]=0;
tmp-=chang(t);
}
else if(visted[t]==1&&pre!=i&&t){
dfs(i,rt);
}
}
return ;
}
int main()
{
while(scanf("%d %d %d %d",&n,&m,&k,&c)!=EOF){
if(n+m+k+c==0){
break;
}
first();
while(m--){
int a,b,v;
scanf("%d %d %d",&a,&b,&v);
map[a][b]=v;
}
while(k--){
int a,b;
scanf("%d %d",&a,&b);
value[a]=b;
}
tmp=0;
ans=INF;
dfs(1,0);
printf("%d\n",ans);
}
return 0;
}