这道题其实就是一道很简单的割边的模板题,不过需要处理重边导师意见有点麻烦的事
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int MAXN=20005;
const int MAXM=200005;
struct edge
{
int to,next,id,num;//这个地方需要在原有模板的基础上加上id(边的标号)和num(是否为重边)
bool cut;
} edge[MAXM];
int ans[MAXM];
int head[MAXN],tot;
int low[MAXN],dfn[MAXN],Stack[MAXN];
int Index,top;
bool Instack[MAXN];
bool cut[MAXN];
int add_block[MAXN];
int bridge;
int T,a,b;
long long n,m;
void addedge(int u,int v,int x,int num)//我在传递四个值的时候对了,不传递num的时候没有处理好
{
edge[tot].to=v;
edge[tot].next=head[u];
edge[tot].cut=false;
edge[tot].id=x;
edge[tot].num=num;
head[u]=tot++;
}
void tarjan(int u,int pre)
{
int v,k=1;
low[u]=dfn[u]=++Index;
Stack[top++]=u;
Instack[u]=true;
int son=0,sum=0;
for(int i=head[u]; i!=-1; i=edge[i].next)
{
v=edge[i].to;
if(v==pre)
continue;
if(!dfn[v])
{
son++;
tarjan(v,u);
if(low[u]>low[v])
low[u]=low[v];
if(low[v]>dfn[u]&&edge[i].num!=1)
{
bridge++;
edge[i].cut=true;
edge[i^1].cut=true;
ans[bridge]=edge[i].id;//这里直接是边的标号
}
}
else if(low[u]>dfn[v])
low[u]=dfn[v];
}
if(u==pre)
add_block[u]=son-1;
Instack[u]=false;
top--;
}
void init()
{
tot=0;
bridge=0;
Index=0;
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(Instack,0,sizeof(Instack));
memset(add_block,0,sizeof(add_block));
memset(edge,-1,sizeof(edge));
memset(head,-1,sizeof(head));
memset(ans,0,sizeof(ans));
}
int main()
{
ios::sync_with_stdio(false);
cin>>T;
while(T--)
{
init();
cin>>n>>m;
for(int i=1; i<=m; i++)
{
cin>>a>>b;
for(int j=head[a]; j!=-1; j=edge[j].next)
if(edge[j].to==b)
{
edge[i].num=1;
}
addedge(a,b,i,edge[i].num);
addedge(b,a,i,edge[i].num);
}
for(int i=1; i<=n; i++)
{
tarjan(i,i);
}
cout<<bridge<<endl;//对输出进行处理的时候,首先需要考虑输出空行的问题,然后还需要需要考虑没有桥的时候,在这里吃了好大的亏,一直WA到死
sort(ans+1,ans+bridge+1);
for(int i=1,u=bridge; i<=bridge; i++)
{
cout<<ans[i];
if(--u)
cout<<" ";
}
if(bridge)
cout<<endl;
if(T)
cout<<endl;
}
return 0;
}
时间: 2024-10-16 04:29:53