E. Exits in Excess(图论+思维)

You own a disco called the Boogie Always Persists Club.The club is famous for its multiple interconnected rooms to twist and shout in. The rooms and the corridors between them form a maze-like structure and for added bonus you have made all the corridors one-way. However, it turns out not everyone is as happy with your club as you are. Recently the fire safety inspectors came by and they were not amused by what they saw: if a fire were to break out in one of the rooms, people would have great difficulty finding the fire exits and might even start running around in circles! They find this completely unacceptable and order you to improve things as quickly as possible. They insist that you have to make sure that no one can run around in circles in the club by removing some of the corridors between the rooms.

You, on the other hand, want to retain the attractiveness of the rooms. You do not want to remove too many corridors, because then people will no longer visit your club. You decide that at most half of the corridors may be removed.

Given the layout of the club, remove at most half of the corridors so that no cycles remain.

image.jpg

INPUT:

• One line containing the number of rooms 1 ≤ n ≤ 10^5 and the number of corridors 0 ≤ m ≤ 2 · 10^5.

• Then follow m lines, each containing two different 1-based integers u and v indicating a corridor from room u to room v. There will be no corridor from a room to itself, nor will there be more than one corridor from one room to any other single room.

OUTPUT:

• On the first line, print a single integer 0 ≤ r ≤ m/2, the number of corridors to be removed.

• Then print r lines containing the 1-based indices of the corridors that need to be removed to ensure that dancers cannot go around in circles in the disco anymore.

If there are multiple valid solutions, you may output any one of them.

Sample Input 4-5 Sample Output 4-5
4 5
1 2
2 3
2 4
3 1
4 1 2
4
5
4 3
1 2
2 3
3 4 1
2
本题答案不唯一,符合要求的答案均正确

样例输入1复制
2 2
1 2
2 1
样例输出1复制
1
2
样例输入2复制
3 3
1 2
2 3
3 1
样例输出2复制
1
1
样例输入3复制
4 5
1 2
1 3
3 2
2 4
3 4
样例输出3复制
0
这道题确实没想到。。。。。我当时写的把一个点孤立出来(或者把一个点的出边或者入边删除),结果wa了,之后发现孤立的一个点尽管取出度+入度最小值,但是还是一样的可能会超出m/2;所以看了题解才知道,原来可以这样写,直接判断v,u大小即可;因为是一个有向图,所以点的可以按照点的大小来分类;
v<u那么加入in中;
v>u那么加入out中;
in和out集合他们都不能单独形成一个环,所以直接输出一个最小的size集合就行;
但是有个问题,怎么就能知道in.size和out.size中小的那个size一定<=m/2呢?
其实可以想到这点:一个完全有向图边数为n*(n-1)==m;而需要去掉的边最多为n;
所以n*(n-1)/2-n=int((nn-2n)/2)>=0;
所以输出的其实就肯定是<=m/2的值了
代码:

#include<bits/stdc++.h>
using namespace std;
vector<int> in,out;
int main(){
    
    
	 int n,m;
	 scanf("%d %d",&n,&m);
	 int x,y;
	 for(int i=0;i<m;i++){
    
    
	 	  scanf("%d %d",&x,&y);
	 	  if(x<y)in.push_back(i+1);
	 	  else out.push_back(i+1);
	 }
	  if(in.size()<out.size()){
    
    
	  	printf("%d\n",in.size());
	  	for(int i=0;i<in.size();i++){
    
    
	  		  printf("%d\n",in[i]);
		  }
	  }else{
    
    
          printf("%d\n",out.size());
	  	for(int i=0;i<out.size();i++){
    
    
	  		  printf("%d\n",out[i]);
		  }
	  }
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44555205/article/details/104998327