tarjan算法参考:http://kmplayer.iteye.com/blog/604532
#include <iostream>
#include <memory.h>
#include <cstdio>
#include <map>
#include <string>
#include <stack>
#include <vector>
using namespace std;
#define MAX 30
int dfn[MAX],low[MAX],instak[MAX],idx,n,m;
char buf1[30],buf2[30];
bool g[MAX][MAX];
map<string,int>sToNum;
map<int,string>numToS;
stack<int> stak;
void clear(){
idx=0;
sToNum.clear(),numToS.clear();
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(g,0,sizeof(g));
while(stak.size())stak.pop();
}
void tarjan(int u){
dfn[u]=low[u]=++idx;
instak[u]=1;
stak.push(u);
for (int i=0;i<n;++i)
{
if(g[u][i]&&!dfn[i]){
tarjan(i);
low[u]=min(low[u],low[i]);
}else if(g[u][i]&&instak[i]){
low[u]=min(low[u],dfn[i]);
}
}
if(dfn[u]==low[u]){
vector<int>r;
while(stak.size()){
int t=stak.top();stak.pop();
instak[t]=0;
r.push_back(t);
if(t==u)break;
}
for (int i=0;i<r.size();++i)
{
if(i>0)printf(", ");
printf("%s",numToS[r[i]].c_str());
}
printf("\n");
}
}
int main(){
int cas=1;
scanf("%d%d",&n,&m);
while (1)
{
int index=0;
clear();
for (int i=0;i<m;++i)
{
scanf("%s %s",buf1,buf2);
string t1=buf1,t2=buf2;
if(sToNum.find(t1)==sToNum.end()){
sToNum[t1]=index;
numToS[index++]=t1;
}
if(sToNum.find(t2)==sToNum.end()){
sToNum[t2]=index;
numToS[index++]=t2;
}
g[sToNum[t1]][sToNum[t2]]=1;
}
printf("Calling circles for data set %d:\n",cas++);
for (int i=0;i<n;++i)
{
if(!dfn[i])tarjan(i);
}
scanf("%d%d",&n,&m);
if(!n&&!m)break;
else printf("\n");
}
return 0;
}