原理在lrj训练指南P312,模板!不连通图的割边是0!!所以这个题要先判断是否是连通的。另外因为要求是按照输入顺序输出,所以不得不说保存数据很麻烦。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
typedef pair<int,int> Pair;
int n,m,tot,num;
map<string,int>mapp;
map<Pair,int>order;
vector<int>g[10001];
string name[10001];
vector<Pair>ans;
int pre[10001],dfsclock;
bool vis[10001];
int dfs(int u,int fa)
{
int lowu=pre[u]=++dfsclock;
int child=0;
for(int i=0; i<(int)g[u].size(); i++)
{
int v=g[u][i];
if(!pre[v])
{
child++;
int lowv=dfs(v,u);
lowu=min(lowv,lowu);
if(lowv>pre[u])
{
Pair p;
p.first=u,p.second=v;
if(order[p]==false)
p.first=v,p.second=u;
ans.push_back(p);
}
}
else if(pre[v]<pre[u]&&v!=fa)
lowu=min(lowu,pre[v]);
}
return lowu;
}
void init()
{
for(int i=0; i<n; i++)
g[i].clear();
mapp.clear();
tot=0,num=0;
memset(pre,0,sizeof(pre));
memset(vis,false,sizeof(vis));
dfsclock=0;
ans.clear();
}
int cmp(Pair a,Pair b)
{
return order[a]<order[b];
}
void dff(int u)
{
vis[u]=true;
for(int i=0; i<(int)g[u].size(); i++)
{
int v=g[u][i];
if(!vis[v])
dff(v);
}
}
int presolve()
{
dff(1);
for(int i=1; i<=n; i++)
if(!vis[i])
return 0;
return 1;
}
int main()
{
// freopen("in.txt","r",stdin);
int cas;
cin>>cas;
while(cas--)
{
cin>>n>>m;
init();
for(int i=0; i<m; i++)
{
string a,b;
cin>>a>>b;
if(mapp[a]==false)
{
mapp[a]=++tot;
name[tot]=a;
}
if(mapp[b]==false)
{
mapp[b]=++tot;
name[tot]=b;
}
Pair p;
int s=mapp[a],t=mapp[b];
p.first=s,p.second=t;
order[p]=++num;
g[s].push_back(t);
g[t].push_back(s);
}
if(!presolve())
{
cout<<0<<endl;
continue;
}
dfs(1,-1);
int t=(int)ans.size();
cout<<t<<endl;
sort(ans.begin(),ans.end(),cmp);
for(int i=0; i<t; i++)
cout<<name[ans[i].first]<<" "<<name[ans[i].second]<<endl;
}
return 0;
}