
并查集+01背包
import java.util.*;
public class Main {
static int n,m,q;
static int cost[],val[];
static int fa[];
public static void main(String args[])
{
Scanner in=new Scanner(System.in);
n=in.nextInt();
m=in.nextInt();
q=in.nextInt();
fa=new int[n+1];
cost=new int[n+1];
val=new int[n+1];
//初始化
for(int i=1;i<=n;i++)
{
fa[i]=i;
cost[i]=in.nextInt();
val[i]=in.nextInt();
}
while(m!=0)
{
int l,r;
l=in.nextInt();
r=in.nextInt();
merge(l,r);
m--;
}
//找到根节点,记录为一个集合物品
int c[]=new int[n+1];//价格
int d[]=new int[n+1];//价值
int an=0;
for(int i=1;i<=n;i++)
{
if(i==fa[i])
{
c[++an]=cost[i];
d[an]=val[i];
}
}
//物品从1开始
int dp[]=new int[q+1];
Arrays.fill(dp, 0);
for(int i=1;i<=n;i++)
{
for(int j=q;j>=c[i];j--)
{
dp[j]=Math.max(dp[j],dp[j-c[i]]+d[i]);
}
}
System.out.println(dp[q]);
}
public static int find(int x)
{
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
public static boolean merge(int x,int y)
{
int u=find(x);
int v=find(y);
if(v==u) return false;
cost[v]+=cost[u];
val[v]+=val[u];
fa[u]=v;
return true;
}
}