def merge_bookings(bookings):
    """Merge overlapping or touching time ranges per room.

    bookings: list of dicts like {"room": "A", "start": 9, "end": 11}
    Times are integers (hours). A booking that starts exactly when another
    ends counts as touching and must be merged.
    Return: dict room -> list of (start, end) tuples, sorted by start.
    Bookings with end <= start are invalid and must be ignored.
    """
    result = {}
    by_room = {}
    for b in bookings:
        by_room.setdefault(b["room"], []).append((b["start"], b["end"]))
    for room, ranges in by_room.items():
        merged = []
        for start, end in ranges:
            if merged and start < merged[-1][1]:
                merged[-1] = (merged[-1][0], end)
            else:
                merged.append((start, end))
        result[room] = merged
    return result
