2020华为软件精英挑战赛-有向图找环

初赛找环,复赛还是找环。初赛没有用到权重(金额),复赛对数据进行加强,同时对相邻两次转账的金额做了限制。

初赛用的单线程,最好成绩:0.2854, 进入了32强。复赛用了多线程,A榜最好成绩:6.1117。多线程负载均衡搞得很差,后面要多学习学习。

 初赛最开始用的python,太耗时间了,根本没有办法比赛。这个比赛对于python 和 java选手是不太友好的。初赛后期就转为C++了,刚好可以学习一下C++。

第一次参加这种类型的比赛,总体的感受是收获很多,每天都能学到新的知识。之前没有学过数据结构,这次算是学到了点皮毛。之前写代码,耗时差不多就行,这次算是开了眼,前排大佬们各种骚操作。初赛最后,大佬们直接把线上数据集刺探透了,整个排行榜开始严重内卷。复赛初期,由于线上数据集太弱,又开始卷了。好在官方接受了选手们的意见,增强了数据集。

贴一下初赛的代码,复赛太长了就不贴了。

//
// Created by root on 4/10/20.
//
#include 
#include 
#include 
#include 
using namespace std;
//#define  TEST

struct  Edge
{
    int ida;
    int idb;
//    int money;
};

struct Slice {
    int* arr;
    int  n;
    int* begin() { return arr; }
    int* end() { return arr + n; }
};


#define edgesnum 280000 
#define nodenum 280000

int feats[edgesnum][3]={0};//保存输入的边,起点id,终点id, 金额 
int featscnt=0;

int nodeidmax = 0;
int graph[nodenum][50]={0}; //保存图,图的出度小于50 
int graph_size[nodenum]={0};//保存每个点的出度数量 

int graphR[nodenum][50]={0};//保存反向图,图的入度小于50 
int graphR_size[nodenum]={0};//保存每个点的入度数量 

char CID[nodenum][8]={"\0"};
char *(CIDpt[nodenum])={NULL};

int nodetoi[nodenum][50]={0}; // 保存以点j为起点,经过 k到达 i的路径。只用保存k就可以。 
int nodetoi_size[nodenum]={0};

int res_cnt[8] = {0,0,0,0,0,0,0,0};
int res3[1000000][3]={0};//保存环3的结果 
int res4[1000000][4]={0};
int res5[1000000][5]={0};
int res6[2000000][6]={0};
int res7[3000000][7]={0};//保存环7的结果 

char buf[200000000];//保存最后要写入文件的内容 


inline int fast_atoi( const char * str )
{
	/*将字符串变成整型数*/ 
    int val = 0;
    while( *str!=',' ) {
        val = val*10 + (*str++ - '0');
    }
    return val;
}

void load_testdata(string &test_dataf) { 
    char *buf;
    int test_data_size = 0;
    int fd = open(test_dataf.c_str(), O_RDONLY);
    test_data_size = lseek(fd, 0, SEEK_END);
    buf = (char*)mmap(NULL, test_data_size, PROT_READ, MAP_PRIVATE, fd, 0);
    char *p = buf;
    int temp1 = 0,temp2 = 0;
    while((p-buf) < test_data_size) {
        temp1 = fast_atoi(p);
        while (*p != ',') // 其实这里可以fast_atoi放进来展开写,那样就舍去了下面的p++操作。但是改完发现变慢了一点,玄学了。 
            p++;
        p++;
        temp2 = fast_atoi(p);
        while (*p != ',')
            p++;
        p++;
        while (*p != '\n')// 由于不需要金额,就略过了。 
            p++;
        p++;
        feats[featscnt][0]=temp1;
        feats[featscnt][1]=temp2;
        featscnt+=1;
    }
}


void build_graph()
{
	/*建立正向图和反向图, 并对度数大于1的进行排序, 同时保存每个id的字符串*/ 
    for(int i=0; i0 )
            notemptycount1+=1;
    }

#endif

    for (int i=0; i< nodenum; ++i)
    {
        if (graph_size[i]>0) {
			nodeidmax = i;
            sprintf(CID[i], "%d", i);
			CIDpt[i] = CID[i];
            if (graph_size[i] > 1) {
                sort(graph[i], graph[i] + graph_size[i]);
            }
        }
    }
    for (int i=0; i< nodenum; ++i) {
        if (graphR_size[i] > 1) {
            sort(graphR[i], graphR[i] + graphR_size[i]);
        }
    }

#ifdef TEST
    //
    int notemptycount2=0;
    for (int i=0; i< nodenum; ++i)
    {
        if (graph_size[i]>0)
            notemptycount2+=1;
    }
    cout<<  "graph size(topobefore):" << notemptycount1 << " graph size(topoafter):" << notemptycount2 << endl;

#endif
}


void res_fromgraph()
{
	/*开始找环, 对于每个起点i,先反向找2步,并且记录反向第3个点中能够到达i的点;再正向4步*/
    /*每次对于小于i的直接剪掉,因为题目要求每个环的起点id要最小*/ 
//    NodePath nodepath;
    int pathtemp[7] = {0};
    bool vist[nodenum]={false};

    vector glrecord;
    vector nodetoi_jumptwo_flag(nodenum, false);//jump two node

    vector gjrecord;
    vector nodetoi_flag(nodenum, false);//jump one node

    int i = 0;
	int loopnum = nodeidmax + 1;
    for (; ii) {
                    nodetoi[gj][nodetoi_size[gj]] = gk;
                    ++nodetoi_size[gj];
                    nodetoi_flag[gj] = true;
                    gjrecord.push_back(gj);
                    for(auto &gl:Slice{graphR[gj], graphR_size[gj]}){
                        if (gl>i and gl!=gk)
                        { 	nodetoi_jumptwo_flag[gl] = true;
                            glrecord.push_back(gl);
                        }
                    }
                }
            }
        }


        vist[i] = true;
        pathtemp[0] = i;

        for(auto &node_j2: Slice{graph[i], graph_size[i]})
        {
            if (node_j2 < i)
                continue;
            vist[node_j2] = true;
            pathtemp[1] = node_j2;
            for (auto &node_j3:Slice{graph[node_j2], graph_size[node_j2]})
            {
                if (node_j3 <= i)
                    continue;
                vist[node_j3] = true;
                pathtemp[2] = node_j3;

                for (auto &node_j4:Slice{graph[node_j3], graph_size[node_j3]})
                {
                    if (node_j4 < i)
                        continue;
                    if (node_j4 == i)
                    {
                        memcpy(res3[res_cnt[3]], pathtemp, sizeof(int)*3);
                        ++res_cnt[3];
                        continue;
                    }
                    if(vist[node_j4])
                        continue;
                    vist[node_j4] = true;
                    pathtemp[3] = node_j4;

                    if (nodetoi_flag[node_j4]) {
                        for (auto &node_j4toi:Slice{nodetoi[node_j4], nodetoi_size[node_j4]}) {
                            if (vist[node_j4toi]) {
                                continue;
                            }
                            pathtemp[4] = node_j4toi;
                            memcpy(res5[res_cnt[5]], pathtemp, sizeof(int)*5);
                            ++res_cnt[5];
                        }
                    }

                    for (auto &node_j5:Slice{graph[node_j4], graph_size[node_j4]})
                    {
                        if (node_j5 < i)
                            continue;
                        if (node_j5 == i) {
                            memcpy(res4[res_cnt[4]], pathtemp, sizeof(int)*4);
                            ++res_cnt[4];
                            continue;
                        }
                        if (vist[node_j5])
                            continue;
                        vist[node_j5] = true;
                        pathtemp[4] = node_j5;

                        if (nodetoi_flag[node_j5]){
                            for (auto &node_j5toi:Slice{nodetoi[node_j5], nodetoi_size[node_j5]}) {
                                if (vist[node_j5toi]) {
                                    continue;
                                }
                                pathtemp[5] = node_j5toi;
                                memcpy(res6[res_cnt[6]], pathtemp, 24);
                                ++res_cnt[6];
                            }
                        }

                        if (!nodetoi_jumptwo_flag[node_j5])
                        {
                            vist[node_j5] = false;
                            continue;
                        }
                        for (auto &node_j6:Slice{graph[node_j5], graph_size[node_j5]})
                        {
                            if (!vist[node_j6] and nodetoi_flag[node_j6])
                            {
                                pathtemp[5] = node_j6;
                                for (auto &node_j6toi:Slice{nodetoi[node_j6], nodetoi_size[node_j6]}) {
                                    if (vist[node_j6toi])
                                        continue;
                                    else {
                                        pathtemp[6] = node_j6toi;
                                        memcpy(res7[res_cnt[7]], pathtemp, 28);
                                        ++res_cnt[7];
                                    }
                                }
                            }
//                            vist[node_j6]=false;
                        }
                        vist[node_j5] = false;
                    }
                    vist[node_j4] = false;
                }
                vist[node_j3] = false;
            }
            vist[node_j2] = false;
        }
        vist[i] = false;
    }
}


inline char* mystrcat( char* dest, char* src )
{
    while (*dest) dest++;
    while (*dest++ = *src++);
    return --dest;
}

void save_fwrite(string &outfile){
	/*保存输出*/ 
    FILE *fp = fopen(outfile.c_str(), "wb");
    char cntnum[50]={'\0'};
	char *cntnumptr = cntnum;  
    char *bpt=buf;

    int rescnt=0;
    char idcomma = ',';
    char idlf = '\n';
    for (int i=3; i<8;++i)
    {
        rescnt += res_cnt[i];
    }

   	sprintf(cntnum,"%d\n",rescnt);
    bpt = mystrcat(bpt, cntnumptr);
	
    int j = 0;

    for (j=0; j

 

你可能感兴趣的:(比赛)