Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 一种快速检查图边列表中连通顶点的方法_Java_Algorithm_Data Structures_Graph - Fatal编程技术网

Java 一种快速检查图边列表中连通顶点的方法

Java 一种快速检查图边列表中连通顶点的方法,java,algorithm,data-structures,graph,Java,Algorithm,Data Structures,Graph,/例如:我有两张单子 列表0:[1,2,3](即边:0-1,0-2,0-3) 我想检查列表中的顶点是否相互连接,即是否有边1-2、1-3等 我的方法可行,但由于有多个循环,需要花费大量时间。 我的代码需要33秒来输入10^5个顶点,我想把它减少到2秒 这是我的密码: public static void ADACHERY() throws IOException { BufferedReader br = new BufferedReader(new InputStrea

/例如:我有两张单子 列表0:[1,2,3](即边:0-1,0-2,0-3)

我想检查列表中的顶点是否相互连接,即是否有边1-2、1-3等 我的方法可行,但由于有多个循环,需要花费大量时间。 我的代码需要33秒来输入10^5个顶点,我想把它减少到2秒

这是我的密码:

    public static void ADACHERY() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(System.out);
        StringTokenizer st = new StringTokenizer(br.readLine());
        int node = Integer.parseInt(st.nextToken());//total no of vertices
        int c = Integer.parseInt(st.nextToken());//total no of edges
        ArrayList<Integer>[] adj = new ArrayList[node];
        for (int i = 0; i < node; ++i) {
            adj[i] = new ArrayList<Integer>();
        }
        int result=0;
        int neg = 0;
        while (c != 0) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            //adding edges
            adj[a].add(b);
            adj[b].add(a);

             new line of code
            if(!Collections.disjoint(adj[a], adj[b])) neg+=3;

            --c;
        }

        for(int i = 0; i<node; i++) {

            int s = adj[i].size();

         if(s>1) {
            result+= s==2?1: s*(s-1)/2;
                int count = 0;

           }

                }
          result-=neg;
          out.println(result);
                out.close();
}
public static void ADACHERY()引发IOException{
BufferedReader br=新的BufferedReader(新的InputStreamReader(System.in));
PrintWriter out=新的PrintWriter(System.out);
StringTokenizer st=新的StringTokenizer(br.readLine());
int node=Integer.parseInt(st.nextToken());//顶点总数
int c=Integer.parseInt(st.nextToken());//边的总数
ArrayList[]adj=新的ArrayList[节点];
对于(int i=0;i
您的方式是次优的,我闻到这里可能有一些
映射/兑现
优化,但我不了解您的确切格式和任务。 好的,最后我对它进行了优化(第3-4版,lol)
在我那台蹩脚的电脑上,它能运行0.5秒

检查不同的图表以查找此处的任何错误:

   package cherries;

import java.util.Arrays;
import java.util.Random;
//import strings.ToString;
//import timers.YTimer;

public class AdaAndCherries {

    public static void printTable(long[] table, int ySize) {

    for (int i = 0; i < table.length; i++) {
        //System.out.format("%s ", ToString.toBinaryString(table[i]));
        if ((i + 1) % ySize == 0)
            System.out.println();
    }
}

public static void fillRand(int[] pairs) {
    Random r = new Random(System.currentTimeMillis());
    int n = pairs.length;
    for (int i = 0; i < n;) {
        pairs[i++] = r.nextInt(n);
        pairs[i++] = r.nextInt(n);
    }
}

public static void toTables(long[] tables, int pairs[], int rowSize) {

    for (int i = 0; i < pairs.length; i += 2) {
        int i2 = i + 1;
        int from = pairs[i];
        int to = pairs[i2];
        // index = starting index of a table + offset, where offset = to/64
        int tablesIndex = from * rowSize + (to >> 6);
        int shift = to & 63; // offset inside a long digit is to % 64
        long bit = 1L << shift;

        tables[tablesIndex] |= bit;
        // and the same for the table of another node, since graph is bidirectional:
        tablesIndex = to * rowSize + (from >> 6);
        shift = from & 63;
        bit = 1L << shift;
        tables[tablesIndex] |= bit;
    }

}

public static void main(String[] args) {

    int m = 10 * 1000;
    int n = m * 2; // in worst case, n = 2*m

    // array containing entries like
    // [0,1,0,2,2,1,0,3,1,4,5,3
    int[] pairs = new int[n];

    // each node will have lookuptable of booleans, representing ajancted edge
    // this has slightly weird format like
    // 0: [0,1,2,3,0...]
    // 1: [0,1,2,4,0...]
    // 2: [0,1,2,0,0...]
    // this tables, each length of 'nodeLookupSize', are concatenated in 

a 1d array
        // and COMPRIMED AS BOOLEAN FLAGS, each long value has 64 flags
        // then looking for cherries is finding differences between two arrays of flags,
        // means XORing them:
        // [0,1,1,1,0...] (for [0,1,2,3,0...])
        // [0,1,1,0,1...] (for [0,1,2,4,0...])
        // [0,0,0,1,1,0...] then count ones.
        // means 2 cherries found (0,1,3) and (0,1,4) and thats all where node 0
        // participates
        // after checking pairs 0-1,0-2,0-, the node 0 is done, and must be masked out
        // for further pairs like 1-2, etc...
// each row begins from j+1 position, means for 0-3 from position 4, 
        // because nodes before were already handled, 
                // because I XOR over length ~n and ~1+2+...n ~ n^2 times, the

 algo has O(n^3)
            // complexity
            // but because not all nodes are connected to each other, i do less XOR's

        int rowSize = n / 64 + ((n % 64 == 0) ? 0 : 1);
        int allSize = n * rowSize;

        System.out.println("size of lookup table of booleans is : " + allSize + " long values what is "
                + (allSize * 8.0) / 1024 / 1024 + " mb, with length of each table in:" + rowSize
                + " long values of size " + rowSize * 8 + " bytes");

        long[] tables = new long[allSize];

        Arrays.fill(tables, 0);

        //YTimer timer = new YTimer();
        //timer.start();

        // use checks from the page
         int[] small = { 0, 1, 0, 2, 2, 1, 0, 3, 1, 4, 5, 3 }; // must be 5 cherries
        // small = new int []{ 1, 2, 1, 3, 1, 4, 1,0};// must be 6 cherries
        // small = new int []{ 1, 2, 3,2}; // must be 1 cherry

        System.arraycopy(small, 0, pairs, 0, small.length);

        // fill pairs with random nodes in random order
        fillRand(pairs);
        // timer.stopAndPrint("pairs initiaded in:");
        // fill lookup tables from the pair list:
        // timer.start();

        toTables(tables, pairs, rowSize);

        // timer.stopAndPrint("tables filled in:");
        // printTable(tables,rowSize);

        // timer.stopAndPrint("rowSize:" + rowSize);

        int allCherriesCount = 0;

        int n_m_1 = n - 1;
        // timer.start();
        for (int i = 0, tableStart = 0; i < n_m_1; i++, tableStart += rowSize) {
            // System.arraycopy(tables, tableStart, v1Backup, 0, rowSize);
            int summ = 0;
            int tableStart2Base = tableStart + rowSize;
            for (int j = i + 1, tableStart2 = tableStart2Base; j < n_m_1; j++, tableStart2 += rowSize) {
                int tablesIndex = tableStart + (j >> 6);
                int shift = j & 63;
                long bit = 1L << shift;
                // true, if i is connected to j:
                boolean isConnected = (tables[tablesIndex] & bit) != 0;
                if (isConnected) {
                    // System.arraycopy(tables, tableStart2, v2Backup, 0, rowSize);
                    // System.out.println( "connected: " + i + " : " + j);
                    int jNext = j + 1;
                    int kBegin = jNext >> 6;
                    int kMaskShift = jNext & 63;
                    // System.out.println( "kBegin: " + kBegin + ", kMaskShift: " + kMaskShift);
                    long kMaskBit = ~((1L << kMaskShift) - 1);
                    // get first long value:
                    long xor = tables[tableStart + kBegin] ^ tables[tableStart2 + kBegin];
                // apply the mask:
                xor &= kMaskBit;
                summ += Long.bitCount(xor);
                // System.out.println( "first xor is:" + ToString.toBinaryString(xor));
                kBegin++;
                for (int k = kBegin; k < rowSize; k++) {
                    xor = tables[tableStart + k] ^ tables[tableStart2 + k];
                    // System.out.println( "next xor is:" + ToString.toBinaryString(xor));
                    summ += Long.bitCount(xor);
                }

            }

        } // end of iterating over an ajancted list
            // cherriesHisto[i] = summ; // also you could fill histo for fun
        allCherriesCount += summ;

    } // end of main loop.
        // timer.stopAndPrint("cherries found:" + allCherriesCount);
    System.out.println("cherries found:" + allCherriesCount);

}
包装樱桃;
导入java.util.array;
导入java.util.Random;
//导入strings.ToString;
//导入timers.YTimer;
公共级苹果和樱桃{
公共静态void打印表(长[]表,int-ySize){
对于(int i=0;i>6);
int shift=to&63;//长数字内的偏移量为%64
长位=1L>6);
班次=从&63;

bit=1L为什么随机希望将计算时间从33秒减少到2秒?我在spoj解决了一个问题,代码通过了所有测试用例,但超出了时间限制。请添加一些示例输入以及所需结果。或者添加一个指向工作示例github的链接。我发现真正理解它有点困难这是上面代码的问题和测试用例。上面的代码适用于所有给定的测试用例。通过互连,我的意思是,例如,如果连接到顶点[1,2,3]的垂直0具有边[0-1,0-2,0-3,]我想检查0所连接的顶点是否也相互连接,即是否存在边1-2、1-3、2-3等。你是指传递连接吗?因为如果你不明白,如果你有所有连接的列表:0:[1,2,3]1:[2,3]你已经有边1-2、1-3了这就是上面代码的问题,如果它解释清楚的话!如果我有像:0->1->2->3->0这样的节点,它算不算4个樱桃?我脑袋里有优化,明天会完成:DYea它应该算4个。谢谢你抽出时间查看。