标签:
题目大意:
给你n个人,m条边,a->b,b->a,才能说这两个人是联通的。问现在有多少个联通圈。输出每个联通圈。n<=25
解题思路:
直接建图,用有向图的闭包传递特性来处理每个人之间的联通关系。然后dfs一次,遍历邻接矩阵中与某个点相连的几个点,边遍历, 边打印输出。
代码:
# include<cstdio> # include<iostream> # include<map> # include<cstring> # include<vector> # include<set> using namespace std; # define MAX 55 map<string,int>MP; vector<string>name; int e[MAX][MAX]; int vis[MAX]; int n,m; int change ( string s ) { for ( int i = 0;i < name.size();i++ ) { if ( name[i]==s ) return i; } name.push_back(s); return name.size()-1; } void dfs( int u ) { vis[u] = 1; for ( int v = 0;v < n;v++ ) { if ( vis[v]==0&&e[u][v]&&e[v][u] ) { cout<<","<<" "<<name[v]; dfs(v); } } return; } int main(void) { int icase = 1; while ( scanf("%d%d",&n,&m)!=EOF ) { if ( n==0&&m==0 ) break; memset(e,0,sizeof(e)); name.clear(); while ( m-- ) { string s1,s2; cin>>s1>>s2; int t1 = change(s1); int t2 = change(s2); e[t1][t2] = 1; } for ( int i = 0;i < n;i++ ) e[i][i] = 1; for ( int k = 0;k < n;k++ ) { for ( int i = 0;i < n;i++ ) { for ( int j = 0;j < n;j++ ) { e[i][j] = e[i][j]||(e[i][k]&&e[k][j]); } } } if ( icase ) puts(""); printf("Calling circles for data set %d:\n",icase++); memset(vis,0,sizeof(vis)); for ( int i = 0;i < n;i++ ) { if (vis[i]==0) { cout<<name[i]; dfs(i); puts(""); } } } return 0; }
11.3.4 例题11-4 UVA 247 Calling Circles (有向图的传递闭包)
标签:
原文地址:http://www.cnblogs.com/lushichuanshuo/p/4856599.html