ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2007年高教社杯全国大学生数学建模竞赛题目 B题:乘公交,看奥运

2020-12-20 15:31:05  阅读:183  来源: 互联网

标签:int Add flag 高教 2007 社杯 Edge dis size


本题的答题意思就是建立公交系统的网络模型,并按照给出的起点终点拿出相应的解决方案,以及对于方案的评价说明,评价说明也许包括最少的换成次数、最短的总体用时(其中乘车以及换乘都给出了理想化的模型时间)、又或是最小化费,当然人与机器的差别在于人有脑子、有七情六欲,在面临现实的情况时我们也许往往不会单纯追求一种代价的最小,(比如当花费时间很短,但是费用相当之高我们显然也是无法接受的),我们都会综合考虑各种各样的因素,现实中也许我们最后选择的方案单独抽出一样代价(时间、费用或者距离)他都不是最优的但是他确实整体最优的,这就需要一个多方面拟合的估价函数

待补充 时间估价函数、记录估价函数、路径记录函数

/*  注:  DEV-C++ 中汉字(包括读取文档的汉字)需用ANSI编码格式  否则读入失败 
	单一票制的情况全是一元  一定程度上化简了本题难度 
	没有两个站的编号是相同的 
	最小花费模型 
	需要注意的是截取第一个汉字需要s.substr(0,2)  因为 一个汉字占位二
	需要完善 最少换乘次数评价函数、
	本人很菜,不然谁建模写C++啊
*/ 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue> 
#define Maxn 100005

using namespace std;
string s;
vector<int> v;
struct Node {
	int p,value;
	bool operator < (const Node &other) const {
        return value > other.value;
    }
};
struct Edge{
    int u,v,w,next;
}e[3000000];
int head[Maxn],tot,flag,dis[Maxn];
bool vis[Maxn];
inline void Add_Edge(int u,int v,int w) {
    e[++tot].u = u,e[tot].v = v,e[tot].w = w,e[tot].next = head[u];
    head[u] = tot;
}

void Dijkstra(int s) {
	priority_queue<Node> q;
	memset(dis,0x7f,sizeof(dis));
	dis[s] = 0; q.push((Node){s,0});
	while(!q.empty()) {
		Node u = q.top(); q.pop();
		if(vis[u.p]) continue;
		vis[u.p] = true;
		for(int i=head[u.p]; i; i=e[i].next) {
			int v = e[i].v,w = e[i].w;
			if(!vis[v] && dis[v] > dis[u.p] + w) {
				dis[v] = dis[u.p] + w;
				q.push((Node){v,dis[v]});
			}
		}
	}
}

inline int Identifier (int p) {// 站点编号处理函数 
    int num = 0;
    num = (s[p] - '0') * 1000 + (s[p + 1] - '0') * 100 + (s[p + 2] - '0') * 10 + s[p + 3] - '0';
    //printf("%d\n",num);
    return num;
}

inline int cost(int num) {// 票价处理函数 
	if(num <= 20) return 1;
	else if(num <= 40) return 2;
	else return 3;
} 

void Alone() {
    int len = s.length();
    v.clear();

    for(int i=0; i<len; i++) {
        if(s[i] == 'S') { //每个站点的标识符S 
            v.push_back(Identifier((i + 1)));
            i += 4;
        }
        else continue;
    }
    int size = v.size();
    for(int i=0; i<size-1; i++) {
    	for(int j=i+1; j<size; j++)
    		Add_Edge(v[i],v[j],flag ? cost(j - i) : 1);// 分段计价 
	}
	//cout << "Alone" << endl;
}

void Double() {
	int len = s.length();
    v.clear();

    for(int i=0; i<len; i++) {
        if(s[i] == 'S') { //每个站点的标识符S 
            v.push_back(Identifier((i + 1)));
            i += 4;
        }
        else continue;
    }
    int size = v.size();
    for(int i=0; i<size-1; i++) {
    	for(int j=i+1; j<size; j++){
    		Add_Edge(v[i],v[j],flag ? cost(j - i) : 1);
    		Add_Edge(v[j],v[i],flag ? cost(j - i) : 1);
		}
	}
	//cout << "Double" << endl;
}

void Circle() {
	int len = s.length();
    v.clear();

    for(int i=0; i<len; i++) {
        if(s[i] == 'S') { //每个站点的标识符S 
            v.push_back(Identifier((i + 1)));
            i += 4;
        }
        else continue;
    }
    int size = v.size();
    for(int i=0; i<size-1; i++) {
    	for(int j=0; j<size; j++){
    		Add_Edge(v[i],v[j],flag ? cost(min(j - i,size - j + 1)) : 1);
    		Add_Edge(v[j],v[i],flag ? cost(min(j - i,size - j + 1)) : 1);//双向环 
		} 
	}
	Add_Edge(v[0],v[size - 1],1);//环上的两个端点  肯定只是坐一站车就到 
	Add_Edge(v[size - 1],v[0],1);
}

int main() {
    freopen("1.txt","r",stdin);
    
    while(1) {
    	cin >> s;
        if(s == "END") break;
        cin >> s;
        flag = 0; // 0  琛ㄧず鍗曚竴绁ㄤ环     1  琛ㄧず鍒嗘璁′环
        if(s == "分段计价。") flag  = 1; // 1 代表分段计价 
        else flag = 0; // 0代表大一票价 
        //cout << "flag = " << flag << endl;
        cin >> s;
        if(s.substr(0,2) == "上") {
        	Alone();
        	cin >> s;// 有上行必有下行 
        	Alone();
		}
        else if(s.substr(0,2) == "环") Circle();
        else Double();// 双向 
    }
    int s,t;
    cout << "===" << endl;
    scanf("%d%d",&s,&t);
    cout << s << ' ' << t << endl;
    Dijkstra(s);
    cout << dis[t];// 仅仅是最小花费的估值函数 
    return 0;
}

标签:int,Add,flag,高教,2007,社杯,Edge,dis,size
来源: https://blog.csdn.net/qq_35776409/article/details/111429132

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有