Wind設計了很多機器人。但是它們都認爲自己是最強的,於是,一場比賽開始了~
機器人們都想知道誰是最勇敢的,於是它們比賽搬運一些物品。
它們到了一個倉庫,裏面有n個物品,每個物品都有一個價值Pi和重量Wi,但是有些物品放在一起會爆炸,並且爆炸具有傳遞性(a和b會爆炸、b和c會爆炸則a和c會爆炸)。機器人們可不想因此損失自己好不容易從Wind那裏敲詐來的裝備,於是它們想知道在能力範圍內,它們最多可以拿多少價值的物品。
你能幫助它們嗎?
【輸入格式】
每組測試數據第1行爲n,Wmax,k(0<=n,Wmax,k<=1000)
接下來n行,爲每個物品的Pi,Wi(0<=Pi<=1000,1<=Wi<=10,均爲整數)
再接下來k行,每行2個數字a,b表示a和b會發生爆炸
【輸出格式】
只有一個整數,表示最大可能的價值。
【樣例輸入】
3 10 1
100 1
200 5
10 5
1 2
自己設計的算法wa了。。。還是神犇的厲害。。。
#include <cstring>
#include <cstdio>
#include <iostream>
const int max_n=1001;
using namespace std;
int n,w0,k;
int a,b;
int p[max_n];//price
int w[max_n];//weight
int fa[max_n];//father
int f[max_n];//f[w]值
int t[max_n][max_n];//分組記錄
void in();
void out();
void Union(int x,int y);
void bag();
int find_f(int x);
int main()
{
in();
out();
return 0;
}
void in()
{
cin>>n>>w0>>k;
for (int i = 1 ; i <= n ; i ++ )
{
cin>>p[i]>>w[i];
fa[i]=i;
}
while( k -- )
{
cin>>a>>b;
Union(a,b);
}
for (int i = 1;i<=n;i ++ )
{
a=find_f(i);
t[a][++t[a][0]]=i;
}
}
void out()
{
bag();
printf("%d\n",f[w0]);
}
void bag()
{
for (int k = 1;k <= n;k ++ )
{
if (t[k][0] > 0)
{
for (int j = w0;j >= 0;j --)
{
for (int i = 1 ;i <= t[k][0];i ++ )
{
a = t[k][i];
if (j>=w[a] && f[j]<f[j-w[a]]+p[a])
f[j]=f[j-w[a]]+p[a];
}
}
}
}
}
void Union(int x,int y)
{
int r1=find_f(x);
int r2=find_f(y);
if (r1 != r2) fa[r2]=r1;
}
int find_f(int x)
{
if (fa[x] == x)return x;
fa[x]=find_f(fa[x]);
return fa[x];
}