UVA 247 Floyd算法

题意

N个人,打了M次电话。假设M次电话为边,N个人为点,双向连通的点构成一个电话圈。求所有的电话圈。

题解

先用Flyod算法求出两个点之间是否连通,再用DFS求出电话圈。

代码

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;

public class Main{
    public static void floyd(boolean d[][],int n) {
        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]);
                }
            }
        }
    }
    public static void dfs(int u,int n,boolean d[][],boolean vis[],Map<String, Integer> map,List<String> list)  {
        for(Entry<String, Integer> entry:map.entrySet()){
            if(entry.getValue()==u){
                list.add(entry.getKey());
                break;
            }       
        }
        for(int i=0;i<n;i++){
            if(d[u][i]&&d[i][u]){
                if(!vis[i]){
                    vis[i]=true;
                    dfs(i, n, d, vis, map,list);
                }
            }
        }
    }
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int kase=1;
        while(scanner.hasNext()){
            boolean d[][]=new boolean[50][50];
            boolean vis[]=new boolean[50];
            int n=scanner.nextInt();
            int m=scanner.nextInt();
            if(n+m==0)
                break;
            System.out.println("Calling circles for data set "+kase+":");
            kase++;
            Map<String, Integer> map=new HashMap<String,Integer>();
            int cnt=0;
            for(int i=0;i<m;i++){
                String stra=scanner.next();
                String strb=scanner.next();
                if(!map.containsKey(stra)){
                    map.put(stra, cnt++);
                }
                if(!map.containsKey(strb)){
                    map.put(strb, cnt++);
                }
                d[map.get(stra)][map.get(strb)]=true;
            }
            for(int i=0;i<50;i++){
                d[i][i]=true;
            }
            floyd(d,n);
            for(int i=0;i<n;i++){
                if(!vis[i]){
                    List<String> list=new ArrayList<String>();
                    vis[i]=true;
                    dfs(i, n, d, vis, map,list);
                    for(int j=0;j<list.size();j++){
                        if(j==list.size()-1){
                            System.out.print(list.get(j));
                        }else{
                            System.out.print(list.get(j)+", ");
                        }
                    }
                    System.out.println();
                }
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值