题目链接: hdu
3849
并且按边输入的顺序输出
如果图不连通则直接输出0
根据编号建立无向图
Tarjan搜索无向图的桥
判断Tarjan的深度,小于n说明是不连通图
代码:
//Final Tarjan搜索桥 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #include <map> #include <string> using namespace std; #define MAX 10005 #define MIN(a,b) a<b?a:b struct snode{ int to,next,num; }edge[MAX*20]; char ZM[MAX*10][16]; char ZM2[MAX*10][16]; char ch1[MAX],ch2[MAX]; int visit[MAX],low[MAX],dnf[MAX],pre[MAX],ans[MAX*10],Index,high,kk; void Add_edge(int a,int b,int m) { edge[Index].num=m; edge[Index].to=b; edge[Index].next=pre[a]; pre[a]=Index++; return ; } void Tarjan(int u,int father) { int v,vv; for(v=pre[u];v!=-1;v=edge[v].next) { vv=edge[v].to; if(!visit[vv]) { visit[vv]=1; low[vv]=dnf[vv]=++high; Tarjan(vv,u); low[u]=MIN(low[u],low[vv]); if(low[vv]>dnf[u]) //low[vv]>dnf[u]就是桥 { ans[kk++]=edge[v].num; } } else if(vv!=father) //** { low[u]=MIN(low[u],dnf[vv]); } } } int main() { int n,m,i,k,t,a,b; scanf("%d",&t); while(t--) { map<string,int> HashZS; Index=kk=0; memset(pre,-1,sizeof(pre)); memset(dnf,0,sizeof(dnf)); memset(visit,0,sizeof(visit)); scanf("%d%d",&n,&m); for(i=0,k=0;i<m;i++) { scanf("%s%s",ch1,ch2); if(HashZS[ch1]==0) //map把字符串转换成编号 { HashZS[ch1]=++k; } if(HashZS[ch2]==0) //map把字符串转换成编号 { HashZS[ch2]=++k; } strcpy(ZM[i],ch1); strcpy(ZM2[i],ch2); a=HashZS[ch1]; b=HashZS[ch2]; Add_edge(a,b,i); Add_edge(b,a,i); } low[1]=dnf[1]=visit[1]=high=1; Tarjan(1,-1); if(high!=n) //如果Tarjan的深度小于n则说明图不连通 { printf("0\n"); continue; } sort(ans,ans+kk); //根据边输入的顺序排序 printf("%d\n",kk); for(i=0;i<kk;i++) { printf("%s %s\n",ZM[ans[i]],ZM2[ans[i]]); } } return 0; }