实验七图的应用二(行车路线)

小明和小芳出去乡村玩,小明负责开车,小芳来导航。
小芳将可能的道路分为大道和小道。大道比较好走,每走1公里小明会增加1的疲劳度。小道不好走,如果走小道,小明的疲劳值会快速增加,走s公里小明会增加s2的疲劳度。所有的小道不相交。
例如:有5个路口,1号路口到2号路口为小道,2号路口到3号路口为大道,3号路口到4号路口为大道,4号路口到5号路口为小道,相邻路口之间的距离都是2公里。如果小明从1号路口到5号路口,则总疲劳值为22+2+2+22=4+2+2+4=12。
现在小芳拿到了地图,请帮助她规划一个开车的路线,使得按这个路线开车小明的疲劳度最小。
  
【输入形式】输入的第一行包含两个整数n, m,分别表示路口的数量和道路的数量。路口由1至n编号,小明需要开车从1号路口到n号路口。
接下来m行描述道路,每行包含四个整数t,a,b,c,表示一条类型为t,连接a与b两个路口,长度为c公里的双向道路。其中t为0表示大道,t为1表示小道。保证1号路口和n号路口是连通的。

【输出形式】输出一个整数,表示最优路线下小明的疲劳度。

【样例输入】6 7
1 1 2 3
0 2 3 2
0 1 3 30
0 3 4 20
0 4 5 30
1 3 5 6
0 5 6 1

【样例输出】48

【数据规模与约定】对于25%的评测用例,不存在小道;
对于所有评测用例,1≤n≤8,1≤m≤10,1≤a,b≤n,t是
0或1,c≤100。保证答案不超过100。

#ifndef GRAPH_H
#define GRAPH_H
#include<iostream>
using namespace std;
class Graph
	{
	        private:
			void operator = (const Graph&) {}
			Graph(const Graph&) {}
		public:
			Graph() {}//构造函数 
			virtual ~Graph() {}//析构函数 
			virtual int n() =0;//顶点数目 
			virtual int e() =0;//边数目 
			virtual int first(int v) =0;//与顶点v关联的第一条边 
			virtual int next(int v,int w) =0;//与顶点v关联的在顶点w后的下一条边 
			virtual void clear()=0;//销毁一个图 
			virtual bool setEdge(int v1,int v2,int wght) =0;//设边权 
			virtual bool delEdge(int v1,int v2) =0;//删除边 
			virtual bool isEdge(int i,int j) =0;//判断是否有边 
			virtual int weight(int v1,int v2) =0;//v1-v2边的边权 
			virtual int getMark(int v) =0;//返回标记信号 
			virtual void setMark(int v,int val) =0;//标记数组中做标记 
			//virtual void DFS(Graph *G1,int v,int k) =0;//深搜 
			//virtual void DFS(int v);
			//virtual void Dijkstra(Graph* G,int* D,int s)=0;
			//virtual int minVertex(Graph* G,int* D)=0;
	};
#endif
#ifndef _Graphm
#define _Graphm
#include<iostream>
#include"Graph.h"
using namespace std;
	class Graphm:public Graph
	{
		private:
			int numVertex,numEdge;
			int **matrix;
			int *mark;
		public:
			int **name;
			Graphm();
			~Graphm();
			void Init(int n);
			int n();
			int e();
			int first(int v);
			int next(int v,int w);
			void clear(); 
			bool setEdge(int v1,int v2,int wt);
			bool delEdge(int v1,int v2);
			bool isEdge(int i,int j);
			int weight(int v1,int v2);
			int getMark(int v);
			void setMark(int v,int val);
            void memset();//重置mark数组 
			//void DFS(Graph *G1,int v,int k); 
			//void DFS(int v);
			void print();//输出邻接矩阵 
			int chudu(int v);
			void Dijkstra(Graph* G,int* D,int s);
			int minVertex(Graph* G,int* D);
	};
#endif
#include<iostream>
#include"Graphm.h"
#include<iomanip>
#define UNVISITED 0
#define VISITED 1
#define INF 1<<30 
using namespace std;
	Graphm::Graphm()
	{	
	}
	Graphm::~Graphm()
	{
		clear(); 
	}
	void Graphm::Dijkstra(Graph* G,int* D,int s)
	{
		int i,v,w;
		for(int i=0;i<G->n();i++)
		{
			D[i]=INF;}
			D[0]=0;
			for(i=0;i<G->n();i++)
			{
				v=minVertex(G,D);
				if(D[v]==INF)
				return;
				G->setMark(v,VISITED);
				for(w=G->first(v);w<G->n();w=G->next(v,w))
				if(D[w]>(D[v]+G->weight(v,w)))
				D[w]=D[v]+G->weight(v,w);
			}
	}
	int Graphm::minVertex(Graph* G,int* D)
	{
		int i,v=-1;
		for(i=0;i<G->n();i++)
		{
			if(G->getMark(i)==UNVISITED)
			{
				v=i;
				break;
			}
		}
		for(i++;i<G->n();i++)
		{
			if((G->getMark(i)==UNVISITED)&&(D[i]<D[v]))
			v=i;
		}
		return v;
	}
	void Graphm::Init(int n)
	{
		numVertex=n;
		numEdge=0;
		mark=new int[n];
		for(int i=0;i<numVertex;i++)
			mark[i]=UNVISITED;
		matrix=(int**) new int*[numVertex];
		for(int i=0;i<numVertex;i++)
	    	matrix[i]=new int[numVertex];
	        for(int i=0;i<numVertex;i++)
	    	        for(int j=0;j<numVertex;j++)
	    		{
	    			if(i==j) matrix[i][j]=1;
	    			else matrix[i][j]=0;
			}
	}
	
	int Graphm::n()
	{
		return numVertex;
	}
	
	int Graphm::e()
	{
		return numEdge;
	}
	
	int Graphm::first(int v)
	{
		for(int i=0;i<numVertex;i++)
			if(matrix[v][i]!=INF&&matrix[v][i]!=0) return i;
		return numVertex;
	}
	
	int Graphm::next(int v,int w)
	{
		for(int i=w+1;i<numVertex;i++)
			if(matrix[v][i]!=INF&&matrix[v][i]!=0) return i;
		return numVertex;
	}
	
	void Graphm::clear()
	{
		delete [] mark;
		mark=NULL;//释放后置空 
		for(int i=0;i<numVertex;i++) 
			delete [] matrix[i];
		delete [] matrix;
		matrix=NULL;//释放后置空 
	}
	
	bool Graphm::setEdge(int v1,int v2,int wt)
	{
		if(wt<=0)
		{
			//cout<<"Illegal weight value\n";
			return false;
		}
		if(v1==v2||v1<0||v2<0||v1>=numVertex||v2>=numVertex)
		{
			//cout<<"Illegal vertex\n";
			return false;
		}
		if(matrix[v1][v2]==INF) numEdge++;
		matrix[v1][v2]=wt;
		return true;
	}
	
	bool Graphm::delEdge(int v1,int v2)
	{
		if(v1<0||v2<0||v1>=numVertex||v2>=numVertex||v1==v2)
		{
			//cout<<"Illegal vertex\n";
			return false;
		}
		if(matrix[v1][v2]!=INF) numEdge--;
		matrix[v1][v2]=INF;
		return true;
	}
	
	bool Graphm::isEdge(int i,int j)
	{
		if(i==j||matrix[i][j]==INF) return false;
		return true;
	}
	
	int Graphm::weight(int v1,int v2)
	{
		if(v1<0||v2<0||v1>=numVertex||v2>=numVertex||v1==v2)
		{
			//cout<<"Illegal vertex\n";
			return INF;
		}
		return matrix[v1][v2];
	}
	
	int Graphm::getMark(int v)
	{
		return mark[v];
	}
	
	void Graphm::setMark(int v,int val)
	{
		mark[v]=val;
	}
	
	void Graphm::memset()
	{
		for(int i=0;i<numVertex;i++)
			mark[i]=UNVISITED;	
	}
	/*void Graphm::DFS(int v) 
		{
			queue<int> que;
			que.push(v);
			for(int m=0; m<numVertex; m++) {
				mark[m]=UNVISITED;
			}
			while(!que.empty()) {
				int now=que.front();
				que.pop();
				mark[now]=VISITED;
				for(int i=0; i<numVertex; i++) {
					if(matric[now][i]==1&&mark[i]==UNVISITED&&i!=v) {
						que.push(i);
						matric[v][i]=1;
					}
				}
			}
		}
	*/
/*	void Graphm::DFS(Graph* G1,int v,int k)//k表示出发点 v表示当前遍历的点 
	{
		G1->setMark(v,1);
		for(int w=G1->first(v);w<G1->n();w=G1->next(v,w))
		{
			if(G1->getMark(w)==0)
			{
				
				DFS(G1,w,k);
				name[w][k]=1;
				name[k][w]=1;
				
				
			}
		}
	}
	*/
	void Graphm::print()
	{
		if(matrix==NULL) 
		{
			cout<<"Empty graph\n";
			return;
		}
	        for(int i=0;i<numVertex;i++)
		{
			for(int j=0;j<numVertex;j++)
			{
				if(matrix[i][j]==INF) cout<<'0'<<' ';
				else cout<<matrix[i][j]<<' ';
			}	
			cout<<endl;
		}	
	}
	
	int Graphm::chudu(int v)
	{
		int num=0;
		
		for(int j=0;j<numVertex;j++)
		{
			if(matrix[v][j]!=INF&&matrix[v][j]!=0) num++;
		}
	    return num;
	}
#include <iostream>
#include "Graphm.h"
#define UNVISITED 0
#define VISITED 1
#define INF 1<<30 
using namespace std;
int main() 
{
	int v,e;//定义顶点和边 
	cin>>v>>e;//输入顶点和边
	Graphm G1;
	G1.Init(v);
	for(int i=0;i<e;i++)
	{
		int t,a,b,c;
		cin>>t>>a>>b>>c;
		if(t==1)c=c*c;
		G1.setEdge(a-1,b-1,c);
		G1.setEdge(b-1,a-1,c);
	}
	int d[v];
	int ss;
	G1.Dijkstra(&G1,d,v);
	cout<<d[v-1];
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值