渡轮王国是一个不错的小国,位于N个岛屿上,由M座桥梁连接。所有的桥梁都非常漂亮,深受王国每个人的喜爱。当然,桥梁系统的设计方式使得人们可以从任何岛屿到达任何其他岛屿。
但最近,这个王国遭遇了巨大的悲痛。渡轮王国被伟大的战士乔丹的军队征服,他决定烧毁所有连接岛屿的桥梁。这是一个非常残酷的决定,但约旦的巫师们建议他不要这样做,因为在那之后他自己的军队将无法从一个岛屿到另一个岛屿。所以乔丹决定尽可能多地烧掉桥梁,这样他的军队仍然可以从任何一个岛屿到达任何一个岛屿。
现在,渡轮王国的穷人想知道桥梁会被烧毁。当然,他们无法了解这一点,因为要烧毁的桥梁清单保密。然而,一位老人说你可以帮助他们找到一组肯定不会被烧毁的桥梁。
所以他们来找你并寻求帮助。你能做到吗?
输入
输入包含多个测试用例。输入的第一行是单个整数T(1 <= T <= 20),它是测试用例的数量。随后是T个测试用例,每个测试用例前面都有一个空白行。
每个案例的第一行包含N和M--分别是渡轮王国中的岛屿和桥梁数量(2 <= N <= 10 000,1 <= M <= 100 000)。接下来的M行每行包含两个不同的整数,并描述桥。请注意,一对岛屿之间可能存在多个桥梁。
产量
在每个案例的第一行打印K - 肯定不会被烧毁的桥梁数量。在第二行打印K整数 - 这些桥的数量。桥从一开始编号,因为它们在输入中给出。
连续两个案例应该用一个空行分隔。在最后一个测试用例之后不应该生成空白行。
样本输入
2 6 7 1 2 2 3 2 4 5 4 1 3 4 5 3 6 10 16 2 6 3 7 6 5 5 9 5 4 1 2 9 8 6 4 2 10 3 8 7 9 1 4 2 4 10 5 1 6 6 10
样本输出
2 3 7 1 4
分析:就是求图的桥
#include<bits/stdc++.h>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cmath>
#include<vector>
#include<cstring>
#include<string>
#include<iostream>
#include<iomanip>
#define mset(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int mod=100000007;
const int N=505050;
const int inf=0x3f3f3f3f;
//priority_queue<int,vector<int>,greater<int> >q;
#include <iostream>
#include<vector>
#include<stack>
#include<queue>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=20000;
int n,m;
int low[N],dfn[N],head[N*10];
int sum,bridge,k;int tot;
int uu[N*10];int p;
struct node
{
int v,w,next,id;
}s[N*10];
void init()
{
tot=bridge=k=0;p=0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(s,0,sizeof(s));
memset(uu,0,sizeof(uu));
memset(head,-1,sizeof(head));
}
void add(int u,int v,int c)
{
s[tot].v=v;
s[tot].id=c;
s[tot].next=head[u];
head[u]=tot++;
}
void Trajan(int u,int fa)
{
low[u]=dfn[u]=++k;
int flag=0;
for(int i=head[u];~i;i=s[i].next)
{
int v=s[i].v;
if(v==fa&&!flag)//重边
{
flag++;
continue;
}
if(!dfn[v])
{
Trajan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u])//求桥
{
bridge++;
uu[p++]=s[i].id;
}
}
else
low[u]=min(low[u],dfn[v]);
}
}
int main()
{
// freopen("in.txt","r",stdin);
int t,u,v;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%d",&n,&m);
for(int i=1; i<=m; i++)
{
scanf("%d%d",&u,&v);
add(u,v,i);
add(v,u,i);
}
Trajan(1,-1);
printf("%d\n",bridge);
if(bridge)
{
sort(uu,uu+bridge);
for(int i=0; i<bridge-1; i++)
{
printf("%d ",uu[i]);
}
printf("%d\n",uu[bridge-1]);
}
if(t)puts("");
}
return 0;
}