Another solution that avoids the sub-query (but again, may not be so fast) uses substring_index, sorted by decreasing time for each field from which you want to get the last one, and then using SUBSTRING_INDEX to just grab the first record returned by SUBSTRING_INDEX.
SELECT user_id, SUBSTRING_INDEX(GROUP_CONCAT(`id` ORDER BY `time` DESC), ',', 1), SUBSTRING_INDEX(GROUP_CONCAT(`topic_id` ORDER BY `time` DESC), ',', 1), SUBSTRING_INDEX(GROUP_CONCAT(`time` ORDER BY `time` DESC), ',', 1) FROM posts WHERE topic_id = 1 GROUP BY user_id
source share