无向图求桥边数量,按照题目输入顺序输出桥边。
注意存的brig和边的对应关系。
#include <iostream> #include <cstdlib> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x3f3f3f3f #pragma comment(linker, "/STACK:16777216") #define eps 1e-6 #define ll long long using namespace std; #define M 200003 #define N 10003 int head[N],num,dfn[N],low[N],n,m,idx,brig[M<<1],bum; struct edge { int st,ed,next; }E[M<<1]; void addedge(int x,int y) { E[num].st=x; E[num].ed=y; E[num].next=head[x]; head[x]=num++; } void tarjan(int u,int father) { int i,v; low[u]=dfn[u]=idx++; for(i=head[u];i!=-1;i=E[i].next) { v=E[i].ed; if(v==father)continue; if(dfn[v]==-1) { tarjan(v,u); low[u]=low[u]>low[v]?low[v]:low[u]; if(low[v]>dfn[u])//存第bum个桥对应边的编号 brig[bum++]=i; } else low[u]=low[u]>dfn[v]?dfn[v]:low[u]; } } void init() { memset(dfn,-1,sizeof dfn); memset(head,-1,sizeof head); num=bum=idx=0; } string hash[N]; string s1,s2; bool cmp(int a,int b) { return a<b; } int main() { int icy,i,cnt; scanf("%d",&icy); while(icy--) { scanf("%d%d",&n,&m); init(); map<string,int> mp; cnt=1; for(i=0;i<m;i++) { cin>>s1>>s2; if(!mp[s1]) hash[cnt]=s1,mp[s1]=cnt++; if(!mp[s2]) hash[cnt]=s2,mp[s2]=cnt++; addedge(mp[s1],mp[s2]); addedge(mp[s2],mp[s1]); } tarjan(1,-1); for(i=1;i<=n;i++)//判断图不联通 if(dfn[i]==-1) break; if(i<=n) { printf("0\n"); continue; } printf("%d\n",bum); sort(brig,brig+bum,cmp); for(int j=0;j<bum;j++) { i=brig[j]; if(i&1) i--; cout<<hash[E[i].st]<<' '<<hash[E[i].ed]<<endl; } } return 0; }
hdu3849 By Recognizing These Guys, We Find Social Networks Useful
时间: 2024-10-11 16:14:46