传送门;https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=737
解题思路:
就是一个简单的求割边问题。
#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <vector> #include <algorithm> using namespace std; const int MAXN=10010; const int MAXM=100100; struct Edge{ int to,next; bool cut; }edge[MAXM]; int head[MAXN],tot; void init(){ memset(head,-1,sizeof(head)); tot=0; } void addEdge(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; edge[tot].cut=false; head[u]=tot++; } int DFN[MAXN],LOW[MAXN]; int Index,brige; int Targan(int u,int pre){ DFN[u]=LOW[u]=++Index; int v; for(int i=head[u];i!=-1;i=edge[i].next){ v=edge[i].to; if(v==pre) continue; if(!DFN[v]){ Targan(v,u); if(LOW[u]>LOW[v]) LOW[u]=LOW[v]; if(LOW[v]>DFN[u]){ brige++; edge[i].cut=true; edge[i^1].cut=true; } }else if(LOW[u]>DFN[v]) LOW[u]=DFN[v]; } } void solve(int N){ memset(DFN,0,sizeof(DFN)); Index=brige=0; for(int i=1;i<=N;i++) if(!DFN[i]) Targan(i,i); printf("%d critical links ",brige); vector<pair<int,int> >ans; for(int u = 1;u <= N;u++) for(int i = head[u];i != -1;i = edge[i].next) if(edge[i].cut && edge[i].to > u) { ans.push_back(make_pair(u,edge[i].to)); } sort(ans.begin(),ans.end()); for(int i=0;i<ans.size();i++) printf("%d - %d ",ans[i].first-1,ans[i].second-1); printf(" "); } int main(){ int n; while(scanf("%d",&n)!=EOF){ init(); for(int j=0;j<n;j++){ int u,k,v; scanf("%d (%d)",&u,&k); u++; for(int i=0;i<k;i++){ scanf("%d",&v); v++; addEdge(u,v); addEdge(v,u); } } solve(n); } }