工场outing

来源:互联网 发布:登陆界面模板下载java 编辑:程序博客网 时间:2024/06/10 03:37

工场outing

创新工场家族成员每年会组织一次旅行,公司的hr为了安排旅行路线伤透脑筋, 因为公司party会场被安排到一个景点B, 而大家的宾馆被安排在了另-个景点A。而景点A和景点B之间有若干个景点No .. Ni。 每个旅游景点大家最多只玩一次. 同时每个旅游素点都有一个评分X, 景点之间会有公路相连, 大家都不喜欢走回头路. 所以每条公路只能走一次。 请帮助hr设计一条路线P, 从A景点到B景点. 再

从B景点返回A景点, 途中必须经过若干个景点,同时使得该路线各个景点的评分和r最

大。

第-行输入旅游景点景点的个数n(不包括A市和B市. 0< n <= 100)

接下来的n行, 每行输入字符串s,代表旅游景点i的名称Ni和评分Xi (O < Xi <= 100)

接下来输入k, 表示必去的景点的个数 (o<=k<n)

接下来的k行, 每行输入必去的旅游景点名称

接下来输入公路的条数e

接下来e行. 每行输入公路的起点和终点

输出:

如果没有解:

输出一行NO

如果有解:

第一行输出YEs

第二行输出r(最大的评分和〉

第三行输出路径r 女口果路径不唯一. 输出任意一条

sample Input:

5

N1 10

N2 10

N3 10

N4 10

N5 20

1

N3

8

AN1

N1 NZ

NZ B

B N3

N3 N4

N4 A

BN5

N5 N4

Sample 0utput:

YES

40

A N1 N2 B N3 N4 A

解释: 由于N3必达. 所返回时不能走包含N5的路线

说明:

1.    除了”A”景点以外的景点最多只出现一次(可以为0,也可以l, 不可能重复)

思路:

如下图所示,如果A是结点1,B是结点7.要求从A到B,再从B到A的路径,可以先求出从1到7 的所有路径。这可以用DFS的思想求出Find_All_Path(),具体看代码。

1到7的所有路径有:

1 2 5 7  权重:20

1 3 6 7  权重:20

1 4 7    权重:30

路径用二维数组保存,权重用一维数组保存。

然后可以调用RebuildCurcle()利用连通分量重建回路,一共有Cn2=n(n-1)/2种可能组合。

即1 2 5 7 63 40

1 2 5 7 4 50

1 3 6 7 4 50

调用bool isAllNodeDifferent(vector<int>&Path)//判断每个节点是否只出现一遍

再调用bool isPassKnode(vector<int>&Path,vector<int>& K)//是否经过给定的K个点

再调用voidChooseTheBestPath(vector< vector<int>>& Path,vector<int>& K)找出权重最大的那一条路径即可。

核心代码是Find_All_Path.

#include<stdio.h>#include<iostream>#include<algorithm>#include<stdlib.h>#include<vector> #define Maxsize 100int visited[Maxsize]={0}; #define ERROR -1#define OK 1using namespace std; struct Node{    int Id; //节点标志    struct Node *next;    int weight;//节点权重} ; struct Graph{    struct Node *A[Maxsize];//链式表示法    Graph()     {         for(inti=0;i<Maxsize;++i)             A[i]=NULL;     } }; int Creatgraph(Graph& g/*Graphadj[Maxsize]*/){    int e,i,j,w1,w2,n,k;    struct Node *p,*q;    printf("顶点数(n),边数(e):");    scanf_s("%d,%d",&n,&e);    if(e<0) return ERROR; //边数不能为负    for(k=1;k<=e;k++)    {        printf("\n第%d条边=>\n\t起点序号,终点序号,起点权重,终点权重:",k);        scanf_s("%d,%d,%d,%d",&i,&j,&w1,&w2);//i为边的开始节点,j为边的尾节点        p=(struct Node*)malloc(sizeof(struct Node));        p->weight=w1;        if(!g.A[i])        {            g.A[i]=p;        }        else        {            for(q=g.A[i];q->next;q=q->next);            q->next=p;        }        p->Id=j;        p->next=NULL;         p=(struct Node*)malloc(sizeof(struct Node));        p->weight=w2;        if(!g.A[j])        {            g.A[j]=p;        }        else        {            for(q=g.A[j];q->next;q=q->next);            q->next=p;        }        p->Id=i;        p->next=NULL;    }    return OK; } vector< vector<int> > ResultPath;vector< int > WeightPath; void Find_All_Path( Graph& g,intu,int v,vector<int>&path ) //求有向图G中顶点u到v之间的所有简单路径,k表示当前路径长度{    struct Node *p;     static intWeight=0;    path.push_back(u);    visited[u]=1;     if(u==v) //找到了一条简单路径    {          ResultPath.push_back(path);               WeightPath.push_back(Weight);    }    else    {        for(p=g.A[u];p;p=p->next)        {            int l=p->Id;            if(!visited[l])            {                Weight += g.A[l]->weight;                Find_All_Path(g,l,v,path); //继续寻找                Weight -= g.A[l]->weight;            }        }    }    visited[u]=0;    path.pop_back();} vector< vector<int> > FinalResult;//用二维数组保存所有可能的待选路径void RebuildCurcle(){    size_t i,j;    vector<int> VecTemp;    for( i=0 ; i<ResultPath.size(); ++i )    {        for( j=i+1 ;j<ResultPath.size() ; ++j )        {            VecTemp.insert(VecTemp.end(),ResultPath[i].begin(),ResultPath[i].end());            for(size_tk=ResultPath[j].size()-2 ; k > 0 ;--k)                VecTemp.push_back(ResultPath[j][k]);            VecTemp.push_back( (WeightPath[i]+WeightPath[j]) );            FinalResult.push_back(VecTemp);            VecTemp.clear();           }    }} bool isAllNodeDifferent(vector<int>&Path) //判断每个节点是否只出现一遍{    bool isExisted[100]={false};    for(size_t i=0 ;i<Path.size()-1 ; ++i )//因为Path的最后一个数是路径的权重之和,不需要计算    {        if(!isExisted[Path[i]])            isExisted[Path[i]]=true;        else returnfalse;    }    return true;} bool isPassKnode(vector<int>&Path,vector<int>& K)//是否经过给定的K个点{    size_t i,j;    for( i=0 ; i<K.size() ; ++i )    {        for( j=0 ; j < Path.size();++j )        {            if(K[i] == Path[j])                break;        }        if(j == Path.size())            return false;    }    return true;} void ChooseTheBestPath(vector< vector<int> >& Path,vector<int>& K){    int Max = -1 ;    size_t MaxIndex = -1,j;    for(size_t i=0 ; i<Path.size(); ++i)    {        if(isAllNodeDifferent(Path[i])&& isPassKnode(Path[i],K))        {            j=Path[i].size()-1;            if(j>=0 &&Path[i][j] > Max)            {                Max = Path[i][j];                MaxIndex = i;            }        }    }    for(size_t i=0 ;i<Path[MaxIndex].size() ; ++i )    {        cout<<Path[MaxIndex][i]<<'';    }}void main(){    int v1,v2;    Graph g;     Creatgraph (g);    printf("\n请输入起点:");    scanf_s("%d",&v1);    printf("请输入终点:\n");    scanf_s("%d",&v2);                 vector<int> path;    Find_All_Path(g,v1,v2,path); //在主函数中初次调用,k值应为    cout<<endl;    RebuildCurcle();       for(size_t k=0;k <FinalResult.size();++k)    {        for(size_t j=0 ; j <FinalResult[k].size();++j)        {            cout<<FinalResult[k][j]<<' ';        }        cout<<endl;    }    cout<<endl;    vector<int> K;    K.push_back(3);    ChooseTheBestPath(FinalResult,K);}


 

原创粉丝点击