UVa 247 Calling Circles 经典floyd传递闭包

来源:互联网 发布:程序员的自我修养 ppt 编辑:程序博客网 时间:2024/06/07 21:49

只需将floyd变下形,将原来的G[i][j]=min(G[i][j],G[i][k]+G[k][j])改成G[i][j]=G[i][j]||(G[i][k]&&G[k][j]),

即判断i到j是否有路。

这题将字符串转换为数字编号,用Floyd判断是否连通,最后dfs输出即可。

#include<bits/stdc++.h> const int maxn=1005;const int INF=0x3f3f3f3f;typedef long long LL;using namespace std;int G[maxn][maxn]; //1和0分别表示"连通"和"不连通" vector<string> S;int vis[maxn];int N,M;void init(){S.clear();memset(G,0,sizeof(G));for(int i=0;i<N;i++) G[i][i]=1; //顶点到自己是"连通"的 }int getNum(const string &s) //把字符串转换为编号 {for(int i=0;i<S.size();i++)if(S[i]==s) return i;S.push_back(s);return S.size()-1;}void floyd(){for(int k=0;k<N;k++)for(int i=0;i<N;i++)for(int j=0;j<N;j++)G[i][j]=G[i][j]||(G[i][k]&&G[k][j]);}void dfs(int v){vis[v]=1;for(int i=0;i<N;i++){if(!vis[i]&&G[v][i]&&G[i][v]) //要双向"连通 "{cout<<", "<<S[i];dfs(i);}}}int main(){//freopen("E:\\ACM\\test.txt","r",stdin);int t=1;string a,b;int s,e;while(cin>>N>>M,N+M){init();for(int i=0;i<M;i++) {cin>>a>>b;s=getNum(a);e=getNum(b);G[s][e]=1; //这里是单向的 }floyd();memset(vis,0,sizeof(vis));if(t!=1) puts("");cout<<"Calling circles for data set "<<t++<<":"<<endl;for(int i=0;i<N;i++){if(!vis[i]){cout<<S[i];dfs(i);puts("");}}}return 0;}


阅读全文
0 0