To question 1:
The computation graph is only created for all operations which were used in the forward pass.
Autograd will thus only calculate the gradients for all parameters, which were involved in these calculations.
However, if you are using e.g. an optimizer with running estimates, all parameters with valid running stats will be updated.
Example:
class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.fc1 = nn.Linear(1, 1)
        self.fc2 = nn.Linear(1, 1)
        
    def forward(self, x, idx):
        if idx==0:
            x = self.fc1(x)
        elif idx==1:
            x = self.fc2(x)
        return x

model = MyModel()
optimizer = optim.Adam(model.parameters(), lr=1.)

x = torch.randn(1, 1)
output = model(x, idx=0)
output.backward()
print('fc1.weight.grad ', model.fc1.weight.grad)
print('fc2.weight.grad', model.fc2.weight.grad)

print('Before 1st optimization')
print(model.fc1.weight)
print(model.fc2.weight)

optimizer.step()
optimizer.zero_grad()

print('After')
print(model.fc1.weight)
print(model.fc2.weight)

output = model(x, idx=1)
output.backward()
print('fc1.weight.grad ', model.fc1.weight.grad)
print('fc2.weight.grad ', model.fc2.weight.grad)

print('Before 2nd optimization')
print(model.fc1.weight)
print(model.fc2.weight)

optimizer.step()
print('After')
print(model.fc1.weight)
print(model.fc2.weight)

> 
fc1.weight.grad  tensor([[-0.4842]])
fc2.weight.grad None
Before 1st optimization
Parameter containing:
tensor([[-0.7616]], requires_grad=True)
Parameter containing:
tensor([[-0.8436]], requires_grad=True)
After
Parameter containing:
tensor([[0.2384]], requires_grad=True)
Parameter containing:
tensor([[-0.8436]], requires_grad=True)
fc1.weight.grad  tensor([[0.]])
fc2.weight.grad  tensor([[-0.4842]])
Before 2nd optimization
Parameter containing:
tensor([[0.2384]], requires_grad=True)
Parameter containing:
tensor([[-0.8436]], requires_grad=True)
After
Parameter containing:
tensor([[0.9085]], requires_grad=True)
Parameter containing:
tensor([[0.1564]], requires_grad=True)

I’m not sure I understand the second question completely (I’m not really experienced in RL), but if you select the highest value e.g. via torch.max, only the max value will get a valid gradient:
x = torch.randn(1, 10, requires_grad=True)
out, idx = torch.max(x, 1)
out.backward()
print(x.grad, idx)
> tensor([[0., 0., 0., 0., 0., 1., 0., 0., 0., 0.]]) tensor([5])

Would that work or am I misunderstanding the question?