//在一个图中选取尽可能多没有相同结点的边
#include <stdio.h>
#define MAX 100000
typedef struct Road{
int to;
int next;
}Road;
Road toArray[MAX * 2];
int numOfTos;
int toLastAdded[MAX + 1];
//degree[city]表示与城市city相连的路中,有可能被封的路的数量
int degree[MAX + 1];
int queue[MAX + 1];
int head, tail;
int blocked[MAX + 1];
int roadsBlocked[MAX + 1][2];
int numOfRoadsBlocked;
void addRoad(int from, int to){
numOfTos++;
int toNum = numOfTos;
toArray[toNum].to = to;
toArray[toNum].next = toLastAdded[from];
toLastAdded[from] = toNum;
}
int numOfCities, numOfRoads;
int main(){
freopen("input.txt", "r", stdin);
scanf("%d%d", &numOfCities, &numOfRoads);
int road;
for (road = 1; road <= numOfRoads; road++){
int from, to;
scanf("%d%d", &from, &to);
addRoad(from, to);
addRoad(to, from);
degree[to]++;
degree[from]++;
}
int city;
//先把进出只有一条路的城市给封了,也就是度为1的顶点的连接边给封了
for (city = 1; city <= numOfCities; city++)
if (degree[city] == 1)
queue[tail++] = city;
while (head < tail){
int cityPoped = queue[head++];
if (blocked[cityPoped])
continue;
blocked[cityPoped] = 1;
int cityBlocked = 0;
int toIndex;
for (toIndex = toLastAdded[cityPoped]; toIndex != 0; toIndex = toArray[toIndex].next){
int city = toArray[toIndex].to;
if (blocked[city] == 0){
blocked[city] = 1;
numOfRoadsBlocked++;
roadsBlocked[numOfRoadsBlocked][0] = cityPoped;
roadsBlocked[numOfRoadsBlocked][1] = city;
cityBlocked = city;
break;
}
}
if (cityBlocked != 0){
for (toIndex = toLastAdded[cityBlocked]; toIndex != 0; toIndex = toArray[toIndex].next){
int city = toArray[toIndex].to;
if (blocked[city] == 0){
//因为城市cityPoped和城市cityBlocked之间的路已经封了,所以城市cityBlocked和城市city之间的路不能再封(因为与城市cityBlocked相连的路最多只能封一条),也就是说在与城市city相连的这些路中,有可能被封的路少了一个,也就是度减1
degree[city]--;
if (degree[city] == 1)
queue[tail++] = city;
}
}
}
}
printf("%d\n", numOfRoadsBlocked);
int roadIndex;
for (roadIndex = 1; roadIndex <= numOfRoadsBlocked; roadIndex++)
printf("%d %d\n", roadsBlocked[roadIndex][0], roadsBlocked[roadIndex][1]);
printf("\n");
return 0;
}
URAL 1389 Roadworks
最新推荐文章于 2016-11-30 15:23:39 发布