工场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);}
- 工场outing
- Outing
- Spring Outing
- Spring Outing
- CSU1580: Outing(图论+DP)
- Spring Outing 解题报告
- 【ACM】Spring Outing
- #1154 :Spring Outing
- HDU 1707 Spring-outing Decision
- 微软笔试题《Spring Outing》
- Candy 出去玩 (outing)
- 创新工场
- 工场模式
- 工场很忙
- 工场模式
- 创新工场
- 创新工场
- Problem 1463 - Come to a spring outing
- XML内5个预定义的实体引用
- Linux 下安装Java环境(JDK1.7 ,tomcat)
- 怎么得积分
- C++ 基类和派生类
- makefile 常用函数
- 工场outing
- 2013 成都网络赛
- 动机的秘密
- 过好几个
- leetcode之Search a 2D Matrix
- vmware 安装win7
- Windows Server 2012正式版RDS系列⑥
- HDOJ 4731 - Minimum palindrome 找规律
- RCP handler处理函数中获取当前选择项。