优良城市(递归,成环)

城市之间有单向公路连接,如果某个城市可以进来的城市数量大于出去可以到达的城市数量,则可以说明该城市是优良城市。(来自腾讯19届校招笔试题)
测试:第一行是城市数量n与公路数量m,下面是m行公路,每行两个数据,起始城市与到达城市
7 10
1 2
1 5
2 3
4 1
2 4
5 3
6 2
6 5
6 7
7 3
结果:
3 5
代码如下:

package y2018.m09.d16;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;

public class bestCity {
    static Scanner cin = new Scanner(System.in);
    static List<directedEdge> dEdge = new ArrayList<directedEdge>();
    static boolean[] isCome;

    public static void main(String[] args) {
        while (cin.hasNext()) {
            HashSet<Integer> zhiqianList;
            HashSet<Integer> zhihouList;
            //城市数量
            int n = cin.nextInt();
            //判断成环的依据
            isCome=new boolean[n+1];
            //边的数量
            int num = cin.nextInt();
            for (int i = 0; i < num; i++) {
                dEdge.add(new directedEdge(cin.nextInt(), cin.nextInt()));
            }

            for (int i = 1; i <= n; i++) {
                zhiqianList = zhiqian(i);
                for(int j=1;j<=n;j++){
                    isCome[j]=false;
                }
                zhihouList = zhihou(i);
                for(int j=1;j<=n;j++){
                    isCome[j]=false;
                }
                if (zhiqianList.size() > zhihouList.size()) {
                    System.out.print(i + " ");
                }
            }
        }
    }


    public static HashSet<Integer> zhiqian(int i) {
        isCome[i]=true;
        HashSet<Integer> set = new HashSet<Integer>();
        HashSet<Integer> newset;
        for (directedEdge e : dEdge) {
            if (e.endToStart(i) != 0) {
                if(!isCome[e.endToStart(i)]) {
                    set.add(e.endToStart(i));
                    isCome[e.endToStart(i)] = true;
                }
            }
        }
        if (set.size()!= 0) {
            //遍历之前的集合,去间接到达的城市
            HashSet<Integer> copyset=new HashSet<Integer>();
            for (Integer k : set) {
                newset = zhiqian(k);
                if (newset.size() == 0) {
                    continue;
                }
                for (Integer j : newset) {
                    copyset.add(j);
                }
            }
            for(Integer copy:copyset){
                set.add(copy);
            }
        }
        return set;
    }

    public static HashSet<Integer> zhihou(int i) {
        isCome[i]=true;
        HashSet<Integer> set = new HashSet<Integer>();
        HashSet<Integer> newset;
        for (directedEdge e : dEdge) {
            if (e.startToEnd(i) != 0) {
                if(!isCome[e.startToEnd(i)]) {
                    set.add(e.startToEnd(i));
                    isCome[e.startToEnd(i)] = true;
                }
            }
        }
        if (set.size()!= 0) {
            //遍历之前的集合,去间接到达的城市
            HashSet<Integer> copyset=new HashSet<Integer>();
            for (Integer k : set) {
                newset = zhihou(k);
                if (newset.size() == 0) {
                    continue;
                }
                for (Integer j : newset) {
                    copyset.add(j);
                }
            }
            for(Integer copy:copyset){
                set.add(copy);
            }
            copyset.clear();
        }
        return set;
    }
}

class directedEdge {
    public int start;
    public int end;

    public directedEdge(int start, int end) {
        this.start = start;
        this.end = end;
    }

    public int endToStart(int i) {
        if (end == i) {
            return start;
        }
        return 0;
    }

    public int startToEnd(int i) {
        if (start == i) {
            return end;
        }
        return 0;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值