1.题目
你不是一个 leader,你是一个 president。幸运的是,你有一只精灵,能够实现你的愿望。你的其中一个愿望就是假装你的社会中有 democracy。
社会很简单。社会里有 N N N 个人,编号从 1 1 1 到 N N N,一些人“开心”而另一些很平常(“不开心”)。人类这种生物非常奇妙,人们只在别人不开心时才感到开心。人们共有 M M M 个愿望,编号从 1 1 1 到 M M M, X → Y X \rightarrow Y X→Y代表 X X X 想要 Y Y Y 不开心。一个人 X X X 是开心的当且仅当他的至少一个愿望得到满足。
Democracy 也没那么复杂。有些人说为了实现 democracy,你需要至少一半的人是开心的(或一半的愿望得到满足),但这不全是事实。我刚才说过,你是一个好的 president,而不是一个好的 leader。你可以通过媒体来定义 democracy。因此,在所有的 M M M 个愿望中,你决定实现至少 ⌊ M / 4 ⌋ + 1 \lfloor M/4 \rfloor +1 ⌊M/4⌋+1 个愿望。
剩下的事情就是选出你想实现的愿望,然后精灵会处理好一切。
2.输入
输入包含多组测试数据。第一行包含一个整数 T T T,代表测试数据的组数。接下来的输入中会按顺序给出每组测试数据。
在每组测试数据中,第一行包含两个正整数 N N N 和 M M M,代表社会中人的数量和愿望的数量。接下来 M M M 行每行包含两个整数 X , Y X, Y X,Y,描述了一个愿望: X X X 希望 Y Y Y 不开心。
3.输出
对于每组测试数据,第一行输出一个整数 K K K,代表实现的愿望的数量,第二行输出 K K K 个整数,代表实现的愿望编号,输出的顺序不做限制。
样例
输入
2
3 3
1 2
2 3
3 1
4 4
1 2
2 3
3 4
1 4
输出
1
2
2
1 4
4.提示
【数据范围与限制】
-
1 ≤ T ≤ 10 , 000 1 \leq T \leq 10, 000 1≤T≤10,000
-
2 ≤ N ≤ 100 , 000 2 \leq N \leq 100,000 2≤N≤100,000
-
1 ≤ M ≤ 200 , 000 1 \leq M \leq 200,000 1≤M≤200,000
-
不存在 X X X 希望 X X X 不开心这样的愿望。
-
可能存在多个相同的 X X X 希望 Y Y Y 不开心的愿望。
-
每组数据保证解一定存在。
-
输出任何正确的解都可以。
【样例解释】
第一组测试数据中,我们可以实现最多 1 1 1 个愿望,输出任意一个愿望都是可行的。
第二组测试数据中,另外一个可行的解是实现愿望 1 , 3 1, 3 1,3 和 4 4 4,最少需要实现 2 2 2 个愿望。
emmmmmmmm,蒟蒻表示看不懂……
5.简化题意
给每个点黑白染色,然后一条边合法当且仅当起点为黑色,终点为白色,要使得合法边数量大于等于 ⌊M / 4⌋ + 1 。
转载至 xiaolilsq
6.做法
其实一开始就没半点思路,后来思考半天后百度了一下,在某大佬的博客中找到一句话:
要满足愿望的数量并不多,随机给每个点染色即可。
emmmmmmmmm……这能过吗?
???
7.代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n;
int m;
int t;
int num;
int tot;
int flag;
int a[N];
struct node{
int x,y;
}b[N];
inline int read(){
register int s=0;
register int w=1;
char ch;
ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-'){
w=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<1)+(s<<3)+(ch^48);
ch=getchar();
}
return s*w;
}
inline void write(int s){
register int len=0;
char ch[20];
if(s<0){
putchar((1<<5)+(1<<3)+(1<<2)+1);
s=~s+1;
}
do{
ch[len++]=s%10+(1<<4)+(1<<5);
s/=10;
}while(s>0);
for(int i=len-1;i>=0;i--){
putchar(ch[i]);
}
return ;
}
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
t=read();
while(t--){
n=read();
m=read();
for(int i=1;i<=m;i++){
b[i].x=read();
b[i].y=read();
}
tot=0;
num=m/4+1;
while(tot<num){
tot=0;
for(int i=1;i<=n;i++){
a[i]=rand()%2;
}
for(int i=1;i<=m;i++){
if((a[b[i].x]==true)&&(a[b[i].y]==false)){
++tot;
}
}
}
write(tot);
putchar('\n');
flag=0;
for(int i=1;i<=m;i++){
if(a[b[i].x]&&!a[b[i].y]){
if(!flag){
flag=1;
}
else{
putchar(' ');
}
write(i);
}
}
putchar('\n');
}
//fclose(stdin);
//fclose(stdout);
return 0;
}