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---->b 24 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;
}