How do I restrict a content type to a subset of vocabulary?
I think http://drupal.org/project/term_reference_tree together with views will handle this for you. You will need to set up different views for each content type and then use term_reference_tree together with that view on each content type. As quoted from the module:


  If you want to filter by a view, make sure the view includes the
  taxonomy term ID, and that the items per page is set to unlimited, as
  the widget will only display the items from the first page of results.


Summarised module usage for reference:


Create a view to filter for the terms you want.


Choose Taxonomy for the content, and work on the Master display (not Page or Block)
Add the Name field
Add the Taxonomy term: Term ID field BUT check the "exclude from display" option.
Turn off the pager
For this specific case, add relationship: Parent term; create OR group in filter: (vocab=tags &amp;&amp; (parent.tid={Apples's tid} || tid={Apples's tid}). This gives the Apples term itself and all its child terms.
Possibly needed if view does not work for non-admin users: change the  Disable SQL Rewriting option under Query settings, but beware that means there is zero access checks on your view.

Apply the view to the Term Reference field.


Go to the content type fields page. 
On the Term Reference field in question, click the Edit link at the end of the row. You can now see the "Filter by view" option.  (If not, your view is wrong). Choose your view and save these options.
Now click the link to change the widget: choose Term Reference Tree.