P1250最勇敢的机器人
背景
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会发生爆炸
输出格式
对每组数据输出1行
为最大可能价值
样例1
样例输入1[复制]
3 10 1 100 1 200 5 10 5 1 2
样例输出1[复制]
210
限制
每个测试点1s
思路:用并查集分组,分组背包板子;
#include<cstdio> #include<string> #include<queue> #include<stack> #include<cstring> #include<vector> #include<list> #include<set> #include<map> using namespace std; #define ll long long #define esp 0.00000000001 const int N=1e3+10,M=1e6+10,inf=1e9+10,mod=1000000007; int v[N],w[N]; int dp[N]; int father[N]; int zu; int flag[N]; int m[N][N]; int s[N]; int maxx(int x,int y) { return x>y?x:y; } int findfa(int x) { return x==father[x]?x:father[x]=findfa(father[x]); } void he(int u,int v) { int x=findfa(u); int y=findfa(v); if(x!=y) { father[x]=y; } } void initt(int x) { zu=1; for(int i=1;i<=x;i++) { int v=findfa(i); if(flag[v]==0) flag[v]=zu++; m[flag[v]][s[flag[v]]++]=i; } } int main() { int x,y,z,i,t,j; scanf("%d%d%d",&x,&y,&z); for(i=0;i<=x;i++) father[i]=i; for(i=1;i<=x;i++) scanf("%d%d",&v[i],&w[i]); for(i=1;i<=z;i++) { int u,v; scanf("%d%d",&u,&v); he(u,v); } initt(x); for(i=1;i<zu;i++) { for(t=y;t>=0;t--) { for(j=0;j<s[i];j++) if(t>=w[m[i][j]])dp[t]=maxx(dp[t],dp[t-w[m[i][j]]]+v[m[i][j]]); } } printf("%d\n",dp[y]); return 0; }
时间: 2024-10-14 13:34:15