首页 > 代码库 > uva 247 Calling Circles(Floyd 的简单应用)

uva 247 Calling Circles(Floyd 的简单应用)

最近在看图论的经典算法,

先看的是求单源最短路的dijkstra,优化后的算法用了优先队列,看起来有点复杂。

感觉 弗洛伊德(Floyd) 要比 迪克斯特拉(dijkstra) 更好理解一点,但是Floyd是三层循环,当然会慢很多。一旦数据开大就跪了吧。


floyd可以用来求 两个 连通点间的最短路问题。同时可以得到边权的和,即最短路的长度。

另外一个比较简单的应用,还可以用来判断两点间的连通性。即判断两点是否连通。本题就是弗洛伊德的这种简单用法。


#include<cstdio>
#include<iostream>
#include<cstring>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
#define mem(a) memset(a,0,sizeof(a))

int n,m;
string s1,s2,str[30];
map<string,int> ma;
int g[30][30];
int vis[30];

void init()
{
    mem(g);
    s1.clear();s2.clear();
    for(int i=0;i<30;i++)
        str[i].clear();
    ma.clear();
}

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]);
            }
        }
    }
}
int main()
{
//    freopen("out.txt","w",stdout);
    int kase=0;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0) break;
        int t=0;
        init();
        for(int i=0;i<m;i++)
        {
            cin>>s1>>s2;
            int id1,id2;
            if(ma.count(s1)){
                id1=ma[s1];
            }
            else{
                id1=t;
                str[t]=s1;
                ma[s1]=t++;
            }
            if(ma.count(s2)){
                id2=ma[s2];
            }
            else{
                id2=t;
                str[t]=s2;
                ma[s2]=t++;
            }
            g[id1][id2]=1;
        }
        floyd();
        if(kase) printf("\n");
        kase++;
        printf("Calling circles for data set %d:\n",kase);
        mem(vis);
        for(int i=0;i<n;i++)
        if(!vis[i])
        {
            cout<<str[i];
            for(int j=i+1;j<n;j++){
                if(!vis[j]){
                    if(g[i][j]&&g[j][i]){
                        cout<<", "<<str[j];
                        vis[j]=1;
                    }
                }
            }
            cout<<endl;
        }
    }
    return 0;
}

本题需要对数据加以处理:

实际问题给的是两个人的名字,表示两者之间的关系。但是在使用Floyd算法的时候,“名字”并没有办法直接使用。

所以想到用string数组把每个名字先保存下来,通过其下标来对该名字进行操作。

另外用到了map来判断此名字在之前有没有出现过,从而扩展 名字数组 。


1y菜鸟感觉很好~

uva 247 Calling Circles(Floyd 的简单应用)