小明和小芳出去乡村玩,小明负责开车,小芳来导航。
小芳将可能的道路分为大道和小道。大道比较好走,每走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;
}