Description
Input
(1<n<=1000, 0<m<100000, s != t)
Output
題意很明顯,求兩個點之間的最短路徑,使用單源最短路的DIJ,數據範圍還是蠻大的用vector和優先隊列來做,先來理一下思路,求兩個點的最短路徑,如果最短路徑有多條則輸出花費最小的,可以看出,判斷的時候會加入花費問題,當路徑相等時判斷花費,先用vector存點和邊,把起點壓入隊列,然後不斷的把最小的符合題意的點和邊彈出去鬆弛剩下的點,鬆弛成功入隊,直到隊列爲空。
#include<algorithm>
#include<stdio.h>
#include<queue>
#include<string.h>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
struct node
{
int now;
int len;
int val;
bool operator <(const node &x)const //優先隊列的重載小於符號
{
if(len>x.len)
return true;
else if(len<x.len)
return false;
else if(len==x.len)
{
if(val>x.val)
return true;
else
return false;
}
}
};
struct node2 //vector
{
int next;
int len;
int val;
};
priority_queue<node> que;
int main()
{
int n,m;
int dis[1005];
int use[1005];
int v[1005];
int l,r;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0)
break;
while(!que.empty()) //清空隊列
que.pop();
for(int i=1;i<=n;i++)
v[i]=dis[i]=INF;
memset(use,0,sizeof(use));
vector<node2>a[1005];
int x,y,z,b;
node2 t;
while(m--)
{
scanf("%d%d%d%d",&x,&y,&z,&b);
t.next=y;
t.len=z;
t.val=b;
a[x].push_back(t);
t.next=x;
t.len=z;
t.val=b;
a[y].push_back(t);
}
scanf("%d%d",&l,&r);
dis[l]=0; //加入起點
v[l]=0;
node temp,next;
temp.len=0;
temp.now=l;
que.push(temp);
while(!que.empty())
{
temp=que.top();
que.pop();
if(use[temp.now]==1)
continue;
use[temp.now]=1;
for(int i=0;i<a[temp.now].size();i++)
{
int now=temp.now;
int templen=dis[now]+a[now][i].len;
int tempval=v[now]+a[now][i].val;
if(dis[a[now][i].next]>templen)
{
dis[a[now][i].next]=templen; //更新
v[a[now][i].next]=tempval;
next.now=a[now][i].next;
next.len=templen;
next.val=tempval;
que.push(next); //入隊
}
else if(dis[a[now][i].next]==templen)
{
if(v[a[now][i].next]>tempval)
{
dis[a[now][i].next]=templen;
v[a[now][i].next]=tempval;
next.now=a[now][i].next;
next.len=templen;
next.val=tempval;
que.push(next);
}
}
}
}
printf("%d %d\n",dis[r],v[r]);
}
}