2016华为软件精英挑战赛初赛题目,个人分析与代码,尚未测试代码,因为没有judge系统啊!

来源:互联网 发布:德国拜发测毒素软件 编辑:程序博客网 时间:2024/06/05 08:41

看到题目,首先想到这是一个哈密顿回路的题,但是不是简单的哈密顿回路,因为题目中要求走过的点不是所有点,而是所有点V的一个子集V',所以在求出一个到达终点的路径之后,做一个判断,看path是否经历过所有的V'就行了,而不需要像求哈密顿回路一样,去设置一个数字cur,当cur==V个数时才判断是否能到达终点。

哈密顿回路是np问题,目前比较直观的解法是采用dfs。

因此这道题目对dfs做了考察,另外,题目的输入输出非常繁琐,没有采用空格分割,而是逗号分割,并且还要人写到文件里面去,不是直接输入,这跟我做过这几年ACM题目都不同,先来回顾一下文件的读取方法:


ifstream a("1.csv");if(!a){return;}while(true){int b;char c;a>>b>>c;} 

我们这里b是int型的,c是char型的,那么读取过程就会直接从文件先读取一个int型,再读取一个char型,本题输入的时候也是一个int,一个char,所以采用这个方法就可以了。

再来看题目本身,这个题目输入的是边的信息,而不是图的信息,因为两个点之间可以有多条路径,因此,我们遍历的是边,而不是点。

设置一个path[]数组,数组记录的是这次遍历过程经过的点,设置一个dist变量,记录这次遍历总共已经走过的长度。



通过dfs搜索,但是不以已经搜索点数等于V‘点数截至,而是一直搜索下去,当发现一个线终点是目标重点,则开始计算路径长度,并判断是否全部经过了V’如果路径长度是已知最短的,并且全部经过了V'的点,则更新successPath为当前path,直到遍历完全部情况。

这里有个小剪枝,如果当前path中储存的点数小于V'中的点数,则当发现一条边的终点是所求终点时也不需要进行判断,因为肯定不符合要求。

这种求法非常暴力,因为剪枝太少,但是毕竟是np问题,系统给出的时间是10s就可以看出其复杂程度,

这题肯定还有更多可以剪枝的部分,大家都可以想一想,说不定能拿个奖啊~


#include<iostream>#include<fstream>using namespace std;class line{public:int start;int end;int length;int id;};int pNum;int lNum;bool *ifVisited;bool ifVisitedLine[4801];int startP;int endP;int mustNum;int mustP[51];line l[4801];int path[4801];int successPath[51];int plength=999999;bool success;int pathPNum;void dfs(int cur){if(cur==pNum){return;}for(int i=1;i<=lNum;i++){if(l[i].start==l[path[cur]].end&&ifVisited[l[i].end]==false){if(l[i].end==endP){if(cur>=mustNum){for(int j=1;j<=mustNum;j++){if(ifVisited[j]==false){goto fall;}}int nowLength=0;for(int j=1;j<=cur;j++){nowLength=l[path[j]].length+nowLength;}if(nowLength<plength){plength=nowLength;pathPNum=cur;for(int j=1;j<cur;j++){successPath[j]=path[j];}goto success;}}else{fall:continue;}}else{path[cur]==l[i].id;    ifVisited[i]=true;    dfs(cur+1);    ifVisited[i]=false;}}success:continue;}}int main(){ifstream file("1.csv");char temp;file>>startP>>temp>>endP>>temp;temp='|';mustNum=0;while(temp=='|'){mustNum++;file>>mustP[mustNum];temp='\n';file>>temp;}file.close();file.open("2.csv");lNum=pNum=0;int temp2;while(file>>temp2){lNum++;l[lNum].id=temp2;file>>temp>>l[lNum].start>>temp>>l[lNum].end>>temp>>l[lNum].length;if(pNum<l[lNum].start){pNum=l[lNum].start;}if(pNum<l[lNum].end){pNum=l[lNum].end;}temp2=-1001;}for(int i=1;i<=lNum;i++){ifVisitedLine[i]=false;}ifVisited=new bool[pNum+1];for(int i=1;i<=pNum;i++){ifVisited[i]=false;}ifVisited[startP]=true;plength=0;pathPNum=0;success=false;dfs(1);ofstream file2("3.csv");if(success==true){for(int i=pathPNum-1;i>=1;i--){file2<<l[successPath[i]].end;if(i!=1){file2<<"|";}}}else{file2<<"NA";}return 0;}


7 1
原创粉丝点击