UVa247: Calling Circles 题解

来源:互联网 发布:选择 net java 编辑:程序博客网 时间:2024/06/08 04:59

有很多算法是用floyd求传递闭包

但感觉裸的tarjan效率更高

#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cmath>#include <algorithm>#include <cstdlib>#include <utility>#include <map>#include <stack>#include <set>#include <vector>#include <queue>#include <deque>#include <sstream>#define x first#define y second#define mp make_pair#define pb push_back#define LL long long#define Pair pair<int,int>#define LOWBIT(x) x & (-x)using namespace std;const int MOD=1e9+7;const int INF=0x7ffffff;const int magic=348;struct node{int indexx;int lowlink;}v[148];vector<int> edge[148];int indexx;map<Pair,bool> judge;map<string,int> m;map<int,string> name;int n,e,tot;stack<int> sta;bool visited[148]; void tarjan(int cur){visited[cur]=true;sta.push(cur);v[cur].indexx=v[cur].lowlink=++indexx;int i,x;for (i=0;i<edge[cur].size();i++){x=edge[cur][i];if (v[x].indexx==0){tarjan(x);v[cur].lowlink=min(v[cur].lowlink,v[x].lowlink);}else{if (visited[x]) v[cur].lowlink=min(v[cur].lowlink,v[x].indexx);}}if (v[cur].indexx==v[cur].lowlink){do{x=sta.top();sta.pop();cout<<name[x];visited[x]=false;if (x!=cur) printf(", ");}while (cur!=x);printf("\n");}}int main (){int i,ca=0;string s1,s2;while (scanf("%d%d",&n,&e) && (n || e)){//if (ca) printf("\n");m.clear();name.clear();tot=0;indexx=0;//judge.clear();for (i=1;i<=n;i++) edge[i].clear();for (i=1;i<=n;i++) v[i].indexx=v[i].lowlink=0;for (i=1;i<=n;i++) visited[i]=false;for (i=1;i<=e;i++){cin>>s1>>s2;if (!m[s1]){m[s1]=++tot;name[tot]=s1;}if (!m[s2]){m[s2]=++tot;name[tot]=s2;}//if (judge[mp(m[s1],m[s2])]) continue;edge[m[s1]].pb(m[s2]);//judge[mp(m[s1],m[s2])]=true;}printf("Calling circles for data set %d:\n",++ca);for (i=1;i<=n;i++)if (!v[i].indexx) tarjan(i);}return 0;}


原创粉丝点击