题目大意:
就是一个单源最短路的问题,按照dijkstra算法做就行了。关键是要除了cost最小的问题,就在(dis[ed.to]>=dis[e.to]+ed.dis)的时候更新一下就可以了,不能用有没有访问过该节点来判断需不需要更新。
这题的测试数据非常水,即使你只是简单地敲出了一个最短路,好像也差不多能过。
#include<iostream>
#include<stdio.h>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
int n,m;
struct edge
{
int to;
int dis;
int cost;
bool operator < (edge const & A)const
{
if(dis<A.dis) return true;
if(dis==A.dis)
{
if(cost<A.cost)
return true;
else
return false;
}
return false;
}
};
vector<edge>G[100004];
int s,t;
int dis[1005];
int from,to;
int cost[1005];
priority_queue<edge>q;
int vis[1005];
const int INF = 100000005;
void dijkstra()
{
fill(dis,dis+n+1,INF);//一定要记得初始化到dis+n+1
fill(cost,cost+n+1,INF);
dis[s] = 0;
cost[s] = 0;
memset(vis,0,sizeof(vis));
vector<edge>::iterator ite;
edge e;
e.dis=0;
e.cost=0;
e.to = s;
q.push(e);
while(!q.empty())
{
edge e;
e = q.top();
q.pop();
if(vis[e.to])
{
continue;
}
vis[e.to] = 1;
for(ite = G[e.to].begin();ite<G[e.to].end();ite++)
{
edge ed = *ite;
if(dis[ed.to]>=dis[e.to]+ed.dis)
{
dis[ed.to] = dis[e.to]+ed.dis;
cost[ed.to] = min(cost[ed.to],cost[e.to]+ed.cost);
q.push(ed);
}
}
}
}
int main()
{
while(cin>>n>>m&&n&&m)
{
for(int i = 0 ; i < n ;i++)
G[i].clear();
for(int i = 0 ; i < m;i++)
{
edge tmp;
scanf("%d%d%d%d",&from,&tmp.to,&tmp.dis,&tmp.cost);
G[from].push_back(tmp);
to = tmp.to;
tmp.to = from;
G[to].push_back(tmp);//无向图,要将两条边都压入
}
scanf("%d%d",&s,&t);
dijkstra();
cout<<dis[t]<<" "<<cost[t]<<endl;
}
}
/*
5 5
1 2 4 10
1 3 6 1
3 4 1 1
4 5 2 1
2 5 5 2
1 5
ANS 9 3*/