题意:
给无向图,求割边的数量并按照字典序输出。
输入:
例如:1 (3) 2 0 3 表示1与2、0、3连接
输出:
自己看案例,且每个案例之后输出一个空行
Sample Input
8
0 (1) 1
1 (3) 2 0 3
2 (2) 1 3
3 (3) 1 2 4
4 (1) 3
7 (1) 6
6 (1) 7
5 (0)
0
Sample Output
3 critical links
0 - 1
3 - 4
6 - 7
0 critical links
分析:
直接求出割边并且保存就行了。
记得排序之后再输出。
ps:尝试使用前向星结果wa烂了
代码(不会前向星):
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<algorithm>
#include<sstream>
#include<memory>
#include<utility>
#include<functional>
#include<iterator>
typedef long long ll;
const int inf=0x3f3f3f3f;
const int inn=0x80808080;
using namespace std;
const int maxm=1e3+5;
struct Node{
int a,b;
}temp[maxm];
bool cmp(Node x,Node y){
if(x.a!=y.a){
return x.a<y.a;
}else{
return x.b<y.b;
}
}
vector<int>g[maxm];
int dfn[maxm];
int low[maxm];
int n;
int cnt;
int ans;
void init(){
for(int i=0;i<maxm;i++){
dfn[i]=low[i]=0;
g[i].clear();
}
ans=0;
cnt=1;
}
void dfs(int u,int fa){
low[u]=dfn[u]=cnt++;
for(int i=0;i<(int)g[u].size();i++){
int v=g[u][i];
if(!dfn[v]){
dfs(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]){
Node a;
a.a=min(u,v);
a.b=max(u,v);
temp[ans++]=a;
}
}else if(v!=fa){
low[u]=min(low[u],dfn[v]);
}
}
}
int main(){
while(cin>>n){
init();
for(int i=0;i<n;i++){
int u,k;
scanf("%d (%d)",&u,&k);
while(k--){
int v;
cin>>v;
g[u].push_back(v);
}
}
for(int i=0;i<n;i++){
if(!dfn[i]){
dfs(i,-1);
}
}
sort(temp,temp+ans,cmp);
printf("%d critical links\n",ans);
for(int i=0;i<ans;i++){
printf("%d - %d\n",temp[i].a,temp[i].b);
}
printf("\n");
}
return 0;
}