http://www.patest.cn/contests/mooc-ds/06-2
注意1
使用vector,用vs调试,监视v不能完全显示邻接表,只能监视v[0],v[1],v[2],这样才能完全显示
注意2
单源最短路径,有2层循环
//第一层循环,n-1次
newp = x;
for(int i=0;i<n-1;i++){
//里面有2个小循环,共3步
//第1步,小循环1:更新权值
for(所有与newp直连的边){
if(没有访问过 && dis[]>dis[newp]+该边权值 || dis[]==-1){
//更新
dis[]=dis[newp]+权值;
}
}
//第2步,小循环2:在更新过的点中找到下一个要访问的点
for(所有的点){
if(dis[]<min && visit[]==1 && dis[]!=-1){
min=dis;
newp=j;
}
}
//第3步,找到更新的newp,使其加入到已访问的节点中,在下一个循环里对其更新
visit[newp]=true;
}
#include<cstdio>
#include<vector>
#define max 510
using namespace std;
struct e{
int next;
int len;
int cos;
};
bool visit[max];
int dis[max];
int cost[max];
vector <e> v[max];
void init(){
for(int i=0;i<max;i++){
v[i].clear();
dis[i]=-1;
cost[i]=-1;
visit[i]=false;
}
}
int main(){
freopen("in.txt","r",stdin);
int n,m,s,d;
while(scanf("%d %d %d %d",&n,&m,&s,&d)!=EOF){
init();
for(int i=0;i<m;i++){
int a,b,l,c;
scanf("%d %d %d %d",&a,&b,&l,&c);
e tmp;
tmp.next=a;
tmp.cos=c;
tmp.len=l;
v[b].push_back(tmp);
tmp.next=b;
v[a].push_back(tmp);
}
dis[s]=0;
visit[s]=1;
cost[s]=0;
int newp=s;
for(int i=0;i<n-1;i++){
for(int j=0;j<v[newp].size();j++){
int t=v[newp][j].next;
int d=v[newp][j].len;
int c=v[newp][j].cos;
/*if(visit[t]==true){
continue;
}*/if(visit[t]==false && dis[t]==-1 || dis[t]>dis[newp]+d || dis[t]==dis[newp]+d && cost[t]>cost[newp]+c){
dis[t]=dis[newp]+d;
cost[t]=cost[newp]+c;
}
}
int min=123123123;
for(int j=0;j<n;j++){
if(dis[j]<min && visit[j]==false && dis[j]!=-1){
min=dis[j];
newp=j;
}
}
visit[newp]=1;
}
printf("%d %d\n",dis[d],cost[d]);
}
return 0;
}