http://acm.hdu.edu.cn/showproblem.php?pid=3790
裸题 dijstra板子 两个条件 先求最短路径 再求最小花费
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=2000;
int e[maxn][maxn];
int t[maxn][maxn];
int n,m;
int dis[maxn];
int tis[maxn];
int vis[maxn];
int ans=0;
void dij(int s){
for(int i=1;i<=n;i++){
dis[i]=e[s][i];
tis[i]=t[s][i];
vis[i]=0;
}
dis[s]=0;
tis[s]=0;
vis[s]=1;
for(int i=1;i<n;i++){
int minn=inf;
int u;
for(int j=1;j<=n;j++){
if(!vis[j]&&dis[j]<minn){
minn=dis[j];
u=j;
}
}
vis[u]=1;
for(int v=1;v<=n;v++){
if(!vis[v]){//注意这个点松弛完后不立刻标记即不加入集合 后面还让他去松弛其他点
if(dis[v]>dis[u]+e[u][v]){
dis[v]=dis[u]+e[u][v];
tis[v]=tis[u]+t[u][v];
}
else if(dis[v]==dis[u]+e[u][v]){
tis[v]=min(tis[v],tis[u]+t[u][v]);
}
}
}
}
}
int main(){
while(scanf("%d%d",&n,&m)){
if(n==0&&n==m) break;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i!=j){
e[i][j]=inf;
t[i][j]=inf;
}
else{
e[i][j]=0;
t[i][j]=0;
}
}
}
while(m--){
int x,y,z,c;
cin>>x>>y>>z>>c;
if(z<e[x][y]){
e[x][y]=z;
e[y][x]=z;
t[x][y]=c;
t[y][x]=c;
}
}
int x,y;
scanf("%d%d",&x,&y);
dij(x);
printf("%d %d\n",dis[y],tis[y]);
}
}
[点击并拖拽以移动]