首页 > 代码库 > ZOJ 2588
ZOJ 2588
求一个无向图的桥(可能存在重边),输出割边的数目,并按顺序输出割边的序号(输入的顺序)。
由于内存的限制 , 无法使用邻接矩阵 , 只能用邻接表了 .
第一次用了邻接表,超内存了;
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <string.h> 5 using namespace std; 6 const int N=10002; 7 const int M=1000002; 8 struct edge{ 9 int v,next,id,two=0;10 }e[M];11 int k,first[M],id,count1; //first[i]是以点i为起点的链表头部12 int dfn[N],low[N],bri[M],mun;13 void init(){14 k=1;15 count1=0;16 mun=0;17 id=0;18 memset(first,0,sizeof(first));19 memset(low,0,sizeof(low));20 memset(dfn,0,sizeof(dfn));21 memset(bri,0,sizeof(bri));22 }23 void addedge(int a,int b){ //向图中加边的算法,注意加上的是有向边//b为a的后续节点既是a---->b24 int i;25 for(i=first[a];i;i=e[i].next){26 if(e[i].v==b)break;27 }28 if(i){ //方法稍作修改,用来标注重边29 e[i].two=1;30 return ;31 }32 e[k].v=b;33 e[k].next=first[a];34 e[k].id=id;35 e[k].two=0;36 first[a]=k++;37 }38 void dfs(int u,int far){ //dfn,Tarjan算法 39 dfn[u]=low[u]=++count1;40 for(int i=first[u];i;i=e[i].next){41 int v=e[i].v;42 if(!dfn[v]){43 dfs(v,u);44 low[u]=min(low[u],low[v]);45 if(low[v]>dfn[u]&&!e[i].two){46 bri[mun++]=e[i].id;47 }48 49 }50 else if(v!=far)low[u]=min(low[u],dfn[v]);51 }52 }53 void print(){54 printf("%d\n",mun);55 if(mun>0){56 sort(bri,bri+mun);57 printf("%d",bri[0]);58 for(int i=1;i<mun;i++)59 printf(" %d",bri[i]);60 printf("\n");61 }62 }63 int main(){64 int t,n,m,a,b;65 scanf("%d",&t);66 while(t--){67 init();68 scanf("%d%d",&n,&m);69 while(m--){70 scanf("%d%d",&a,&b);71 id++;72 addedge(a,b);73 addedge(b,a);74 }75 dfs(1,0);76 print();77 if(t)printf("\n");78 }79 return 0;80 }
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
using namespace std;
const int N=10002;
const int M=1000002;
struct edge{
int v,next,id,two=0;
}e[M];
int k,first[M],id,count1;
int dfn[N],low[N],bri[M],mun;
void init(){
k=1;
count1=0;
mun=0;
id=0;
memset(first,0,sizeof(first));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(bri,0,sizeof(bri));
}
void addedge(int a,int b){
int i;
for(i=first[a];i;i=e[i].next){
if(e[i].v==b)break;
}
if(i){
e[i].two=1;
return ;
}
e[k].v=b;
e[k].next=first[a];
e[k].id=id;
e[k].two=0;
first[a]=k++;
}
void dfs(int u,int far){
dfn[u]=low[u]=++count1;
for(int i=first[u];i;i=e[i].next){
int v=e[i].v;
if(!dfn[v]){
dfs(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]&&!e[i].two){
bri[mun++]=e[i].id;
}
}
else if(v!=far)low[u]=min(low[u],dfn[v]);
}
}
void print(){
printf("%d\n",mun);
if(mun>0){
sort(bri,bri+mun);
printf("%d",bri[0]);
for(int i=1;i<mun;i++)
printf(" %d",bri[i]);
printf("\n");
}
}
int main(){
int t,n,m,a,b;
scanf("%d",&t);
while(t--){
init();
scanf("%d%d",&n,&m);
while(m--){
scanf("%d%d",&a,&b);
id++;
addedge(a,b);
addedge(b,a);
}
dfs(1,0);
print();
if(t)printf("\n");
}
return 0;
}