无向图缩块后,以n所在的块为根节点,dp找每块中的最大值.
对于每个桥的答案为两块中的较小的最大值和较小的最大值加1
2 3 2 3 1 2 3 3 3 1 2 2 3 3 1
1 2 2 3 0 0 0 0 0 0
/* *********************************************** Author :CKboss Created Time :2015年08月22日 星期六 10时24分13秒 File Name :HDOJ5409.cpp ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <cstdlib> #include <vector> #include <queue> #include <set> #include <map> using namespace std; const int maxn=100100; typedef long long int LL; typedef pair<int,int> pII; struct Edge { int from,to,next,id; }edge[maxn*2]; int Adj[maxn],Size,n,m; void init() { Size=0; memset(Adj,-1,sizeof(Adj)); } void Add_Edge(int u,int v,int id) { edge[Size].from=u; edge[Size].id=id; edge[Size].to=v; edge[Size].next=Adj[u]; Adj[u]=Size++; } int Low[maxn],DFN[maxn],Stack[maxn],Belong[maxn]; int Index,top,scc; bool Instack[maxn],vis[maxn],ve[maxn*2]; void Tarjan(int u,int fa) { int v; Low[u]=DFN[u]=++Index; Stack[top++]=u; Instack[u]=true; for(int i=Adj[u];~i;i=edge[i].next) { v=edge[i].to; if(v==fa&&ve[edge[i].id]) continue; ve[edge[i].id]=true; if(!DFN[v]) { Tarjan(v,u); Low[u]=min(Low[u],Low[v]); } else { Low[u]=min(Low[u],DFN[v]); } } if(Low[u]==DFN[u]) { scc++; do { v=Stack[--top]; Belong[v]=scc; Instack[v]=false; }while(v!=u); } } void scc_solve() { memset(DFN,0,sizeof(DFN)); memset(Instack,0,sizeof(Instack)); Index=scc=top=0; memset(ve,0,sizeof(ve)); for(int i=1;i<=n;i++) { if(!DFN[i]) Tarjan(i,i); } } int value[maxn]; vector<pII> G[maxn]; int ans[maxn][2]; int bian[maxn][2]; int MX[maxn]; void dfs(int u,int fa) { MX[u]=value[u]; for(int i=0,sz=G[u].size();i<sz;i++) { int v=G[u][i].first; if(v==fa) continue; dfs(v,u); MX[u]=max(MX[u],MX[v]); } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T_T; scanf("%d",&T_T); while(T_T--) { scanf("%d%d",&n,&m); init(); for(int i=0;i<m;i++) { int a,b; scanf("%d%d",&a,&b); bian[i][0]=a; bian[i][1]=b; Add_Edge(a,b,i); Add_Edge(b,a,i); } scc_solve(); /***************REBUILD**********************/ memset(value,0,sizeof(value)); memset(ans,0,sizeof(ans)); int root=0; for(int i=1;i<=n;i++) { G[i].clear(); int b=Belong[i]; value[b]=max(value[b],i); if(value[b]==n) root=b; } //for(int i=1;i<=scc;i++) cout<<i<<" value: "<<value[i]<<endl; for(int i=0;i<m;i++) { int u=Belong[bian[i][0]]; int v=Belong[bian[i][1]]; if(u==v) continue; G[u].push_back(make_pair(v,i)); G[v].push_back(make_pair(u,i)); } dfs(root,root); //for(int i=1;i<=scc;i++) { cout<<i<<" mx: "<<MX[i]<<endl; } for(int i=0;i<m;i++) { int u=Belong[bian[i][0]]; int v=Belong[bian[i][1]]; if(u==v) { puts("0 0"); continue; } else { int mx=min(MX[u],MX[v]); printf("%d %d\n",mx,mx+1); } } } return 0; }