题目描述
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
输入描述:
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。 (1<n<=1000, 0<m<100000, s != t)
输出描述:
输出 一行有两个数, 最短距离及其花费。
示例1
输入
3 2 1 2 5 6 2 3 4 5 1 3 0 0
输出
9 11
#include<iostream>
#include<vector>
using namespace std;
struct E
{
int next;
int cost;
int dis;
};
int D[100001];
int C[100001];
vector<E>edges[100001];
bool mark[100001];
int main()
{
int n,m;
while(cin>>n>>m)
{
for(int i=1;i<=n;i++)
{
D[i]=-1;
C[i]=-1;
mark[i]=false;
edges[i].clear();
}
int a,b,cost,dis;
for(int i=0;i<m;i++)
{
cin>>a>>b>>dis>>cost;
E p;
p.next=a;
p.cost=cost;
p.dis=dis;
edges[b].push_back(p);
p.next=b;
edges[a].push_back(p);
}
int start,end;
cin>>start>>end;
int newp;
newp=start;
D[newp]=0;
C[newp]=0;
mark[newp]=true;
for(int i=1;i<n;i++)
{
for(int j=0;j<edges[newp].size();j++)//当前点newp的所有邻接点
{
int next=edges[newp][j].next;
int d=edges[newp][j].dis;
int c=edges[newp][j].cost;
if(mark[next]==true)continue;
if(D[next]==-1||D[next]>D[newp]+d||(D[next]==D[newp]+d&&C[next]>C[newp]+c))
{
D[next]=D[newp]+d;
C[next]=C[newp]+c;
}
}
int minn=9999;
for(int i=1;i<=n;i++)
{
if(mark[i]==true)continue;
if(D[i]==-1)continue;
if(D[i]<minn)
{
minn=D[i];
newp=i;
}
}
mark[newp]=true;
}
cout<<D[end]<<' '<<C[end]<<endl;
}
}