Uva 247 - Calling Circles(传递闭包 / 强连通分量)

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

【题意】
如果两个人直接或间接互相打电话,则说明他们在同一个电话圈里。例如a打给b,b打给c,c打给d,d打给a,则这4个人在同一个圈里;如果e打给f,但是f不能打回给e,那么e,f就不在一个电话圈里,输入n(n<=25)个人和m次电话,找出所有的电话圈,人名是小写字母且不超过25个字符,不会有重名的情况。

【思路】
两种思路,一种是按照紫书上讲的floyd算法求传递闭包,最后用一个并查集把在同一个圈子中的人记录下来并输出。另一种思路是可以求强连通分量,每个强连通分量中的人都在同一个圈子中。

代码一:floyd求传递闭包

#include<bits/stdc++.h>
using namespace std;

const int maxn = 30;

int n, m, cnt;
char s1[maxn], s2[maxn];
char name[maxn][maxn];
int d[maxn][maxn];
int par[maxn];

void init() {
    cnt = 0;
    memset(name, 0, sizeof(name));
    memset(d, 0, sizeof(d));
    for (int i = 0; i < maxn; ++i) par[i] = i;
}

int find(int x) {
    if (x == par[x]) return x;
    else return par[x] = find(par[x]);
}

void floyd() {//求传递闭包,d[i][j]==1表示i能传递到j
    for (int k = 1; k <= n; ++k) {
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                d[i][j] = d[i][j] || (d[i][k] && d[k][j]);
            }
        }
    }
}

int main() {
    int kase = 0;
    while (scanf("%d%d", &n, &m) == 2) {
        if (!n && !m) break;
        if (kase) printf("\n");
        init();
        for (int i = 1; i <= m; ++i) {
            scanf("%s%s", s1, s2);
            int u = 0, v = 0;
            for (int i = 1; i <= cnt; ++i) {
                if (!strcmp(s1, name[i])) u = i;
                if (!strcmp(s2, name[i])) v = i;
            }
            if (0 == u) { u = ++cnt; strcpy(name[u], s1); }
            if (0 == v) { v = ++cnt; strcpy(name[v], s2); }
            d[u][v] = 1;
        }
        floyd();

        //用并查集把不同圈子的人分到不同的集合中去
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (d[i][j] && d[j][i]) {
                    int x = find(i);
                    int y = find(j);
                    if (x != y) par[x] = y;
                }
            }
        }

        printf("Calling circles for data set %d:\n", ++kase);
        for (int i = 1; i <= n; ++i) {
            if (i != par[i]) continue;
            printf("%s", name[i]);
            for (int j = 1; j <= n; ++j) {
                if (par[j] == i && j != i) printf(", %s", name[j]);
            }
            printf("\n");
        }
    }
    return 0;
}

代码二:Tarjan算法求强连通分量

#include<bits/stdc++.h>
using namespace std;

const int maxn = 30;

int n, m;
int dfs_clock, scc_cnt;
int pre[maxn], lowlink[maxn], sccno[maxn];
vector<int> g[maxn], scc[maxn];
stack<int> s;

void dfs(int u) {
    pre[u] = lowlink[u] = ++dfs_clock;
    s.push(u);
    for (int i = 0; i < g[u].size(); ++i) {
        int v = g[u][i];
        if (0 == pre[v]) {
            dfs(v);
            lowlink[u] = min(lowlink[u], lowlink[v]);
        }
        else if (0 == sccno[v]) {
            lowlink[u] = min(lowlink[u], pre[v]);
        }
    }
    if (lowlink[u] == pre[u]) {
        ++scc_cnt;
        scc[scc_cnt].clear();
        while (1) {
            int x = s.top();
            s.pop();
            sccno[x] = scc_cnt;
            scc[scc_cnt].push_back(x);
            if (x == u) break;
        }
    }
}

void find_scc(int n) {
    dfs_clock = scc_cnt = 0;
    memset(pre, 0, sizeof(pre));
    memset(sccno, 0, sizeof(sccno));
    for (int i = 0; i < n; ++i) {
        if (0 == pre[i]) dfs(i);
    }
}

int cnt;
char s1[maxn], s2[maxn];
char name[maxn][maxn];

int main() {
    int kase = 0;
    while (scanf("%d%d", &n, &m) == 2) {
        if (!n && !m) break;
        if (kase) printf("\n");
        cnt = 0;
        for (int i = 0; i < maxn; ++i) g[i].clear();
        for (int i = 0; i < m; ++i) {
            scanf("%s%s", s1, s2);
            int u = -1, v = -1;
            for (int i = 0; i < cnt; ++i) {
                if (!strcmp(name[i], s1)) u = i;
                if (!strcmp(name[i], s2)) v = i;
            }
            if (-1 == u) { u = cnt; strcpy(name[cnt++], s1); }
            if (-1 == v) { v = cnt; strcpy(name[cnt++], s2); }
            g[u].push_back(v);
        }
        find_scc(n);
        printf("Calling circles for data set %d:\n", ++kase);
        for (int i = 1; i <= scc_cnt; ++i) {
            printf("%s", name[scc[i][0]]);
            for (int j = 1; j < scc[i].size(); ++j) {
                printf(", %s", name[scc[i][j]]);
            }
            printf("\n");
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Description: An attempt was made to call a method that does not exist. The attempt was made from the following location: org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration$PoolBuilderFactory.getPoolConfig(LettuceConnectionConfiguration.java:207) The following method did not exist: 'void org.apache.commons.pool2.impl.GenericObjectPoolConfig.setMaxWait(java.time.Duration)' The calling method's class, org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration$PoolBuilderFactory, was loaded from the following location: jar:file:/D:/Developing%20learning%20software/apache-maven-3.9.2-bin/nfv/org/springframework/boot/spring-boot-autoconfigure/3.1.2/spring-boot-autoconfigure-3.1.2.jar!/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration$PoolBuilderFactory.class The called method's class, org.apache.commons.pool2.impl.GenericObjectPoolConfig, is available from the following locations: jar:file:/D:/Developing%20learning%20software/apache-maven-3.9.2-bin/nfv/org/apache/commons/commons-pool2/2.6.0/commons-pool2-2.6.0.jar!/org/apache/commons/pool2/impl/GenericObjectPoolConfig.class The called method's class hierarchy was loaded from the following locations: org.apache.commons.pool2.impl.GenericObjectPoolConfig: file:/D:/Developing%20learning%20software/apache-maven-3.9.2-bin/nfv/org/apache/commons/commons-pool2/2.6.0/commons-pool2-2.6.0.jar org.apache.commons.pool2.impl.BaseObjectPoolConfig: file:/D:/Developing%20learning%20software/apache-maven-3.9.2-bin/nfv/org/apache/commons/commons-pool2/2.6.0/commons-pool2-2.6.0.jar org.apache.commons.pool2.BaseObject: file:/D:/Developing%20learning%20software/apache-maven-3.9.2-bin/nfv/org/apache/commons/commons-pool2/2.6.0/commons-pool2-2.6.0.jar Action: Correct the classpath of your application so that it contains compatible versions of the classes org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration$PoolBuilderFactory and org.apache.commons.pool2.impl.GenericObjectPoolConfig
最新发布
07-24
The error message suggests that there is a version incompatibility between the classes `LettuceConnectionConfiguration$PoolBuilderFactory` from the Spring Boot autoconfigure library and `GenericObjectPoolConfig` from the Apache Commons Pool library. To resolve this issue, you need to ensure that compatible versions of these libraries are present on your application's classpath. Here's what you can do: 1. Check your application's dependencies: Verify that you have the correct versions of the Spring Boot and Apache Commons Pool libraries specified in your project's dependencies. 2. Resolve version conflicts: If you are using a build tool like Maven or Gradle, ensure that the versions specified for both Spring Boot and Apache Commons Pool are compatible. If there are any conflicting versions, try to align them to a compatible version. 3. Exclude conflicting transitive dependencies: If you are using a build tool, you can exclude the transitive dependencies of Spring Boot or Apache Commons Pool that might be causing conflicts. This can be done by adding exclusion rules in your build file. For example, in Maven, you can exclude a transitive dependency like this: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>3.1.2</version> <exclusions> <exclusion> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </exclusion> </exclusions> </dependency> ``` By resolving any version conflicts and ensuring compatible versions of the libraries are present on the classpath, you should be able to resolve the method not found error.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值