This solution works.
The key is to identify which records need to be joined, (those where the diff in end time between it and the previous record is greater than the diff between it's own start and end time), then join them using groupby.
Repeat until all overlapping records have been merged.
df_txt = """
bl st end
1 100 105
1 105 200
1 195 205
2 1 10
2 10 25
2 15 20
2 18 30
2 30 40"""
df = pd.read_fwf(io.StringIO(df_txt)).rename(columns={'bl':'block','st':'start'})
df['next_end_diff'] = df.groupby('block')['end'].diff()
df['st_to_st_diff'] = df.groupby('block')['start'].diff()
df['st_to_end_diff'] = df['end']-df['start']
df_mask = df['next_end_diff']<df['st_to_end_diff']
df.loc[df_mask,'start'] = df.loc[df_mask,'start'] - df.loc[df_mask,'st_to_st_diff']
df = df.groupby(['block','start'])['end'].max().reset_index()
while sum(df_mask)>0:
df['next_end_diff'] = df.groupby('block')['end'].diff()
df['st_to_st_diff'] = df.groupby('block')['start'].diff()
df['st_to_end_diff'] = df['end']-df['start']
df_mask = df['next_end_diff']<df['st_to_end_diff']
df.loc[df_mask,'start'] = df.loc[df_mask,'start'] - df.loc[df_mask,'st_to_st_diff']
df = df.groupby(['block','start'])['end'].max().reset_index()