Uva247 Floyd传递闭包+map处理

来源:互联网 发布:财务管家婆软件 编辑:程序博客网 时间:2024/05/24 04:53

链接:https://vjudge.net/problem/UVA-247 


题意:a打给b,b打给c,c打给d,d打给a,那么这四个人就在一个圈里,具有传递性,离散数学传递闭包的经典题目,a可以通过bc到达d,因为d可以到达a,所以a和d在一个圈,b可以通过cd到达a,a也可以到达b,所以ab在一个圈。如果e打给f,f不能直接或者间接打给e,那么这两个人就不在一个圈,找出所有的圈。

n最大才25,不怕超时了,floyd三重循环暴力解决

利用floyd的中间传递松弛性恰好解决。

#include <bits/stdc++.h>using namespace std;map<string,int>name;vector<string>Name;int n,m;int vis[30];int d[30][30];int id;//没什么用,就是给name逐增赋值void floyd() {    for(int k = 0; k < n; k++)        for(int i = 0; i < n; i++)            for(int j = 0; j < n; j++)                d[i][j] = d[i][j]||(d[i][k]&&d[k][j]);    }void dfs(int u) {    vis[u] = 1;    for(int i = 0; i < n; i++) {            if(!vis[i]&&d[u][i]&&d[i][u]) {                cout<<", "<<Name[i];                dfs(i);        }    }}int main() {//    freopen("in.txt","r",stdin);    int casen = 1;    while(cin>>n>>m) {        if(n==0&&m==0)            break;            Name.clear();            name.clear();            memset(d,0,sizeof(d));            memset(vis,0,sizeof(vis));            id =0;        while(m--) {            string a,b;            cin>>a>>b;            //count()函数返回map中键值等于key的元素的个数,就只能为            //1或者0,专门判断一个键值值是否存在map里面,前提是这个键值赋了key值。            if(!name.count(a)) {                name[a] = id;                id++;                Name.push_back(a);            }            if(!name.count(b)) {            name[b] = id;            id++;            Name.push_back(b);            }            d[name[a]][name[b]] = 1;        }            floyd();            if(casen>1)                cout<<endl;            printf("Calling circles for data set %d:\n",casen);            casen++;            for(int i = 0; i < n; i++) {                if(!vis[i]) {                    cout<<Name[i];                    dfs(i);                    cout<<endl;;                }            }        }    }


0 0
原创粉丝点击