Dijkstra算法(优先队列优化)
注意:we assume that Mr. M starts from city 1 and his target is city 2.
合法路径:1→1,1→2,2→2 非法路径:2→1
- 距离更新时增加限制:禁止从2转向1
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#include<climits>
using namespace std;
const int maxn=601;
const int INF=INT_MAX;
struct Point{
int next;
int distance;
bool operator <(Point x)const{
return distance>x.distance;
}
Point(int n,int d):next(n),distance(d){}
Point(){}
};
struct Edge{
int to;
int distance;
Edge(int t,int d):to(t),distance(d){}
Edge(){}
};
vector<Edge>graph[maxn];
int dis[maxn];
int leader[maxn];//所属阵营
void Dijkstra(int start,int n){
fill(dis+1,dis+n+1,INF);
dis[start]=0;
priority_queue<Point>myqueue;
myqueue.push(Point(start,0));
while(!myqueue.empty()){
int u=myqueue.top().next;
myqueue.pop();
for(int i=0;i<graph[u].size();i++){
int x=graph[u][i].to;
int y=graph[u][i].distance;
if(leader[u]==2&&leader[x]==1)continue;//禁止从2到1
if(dis[u]+y<dis[x]){
dis[x]=dis[u]+y;
myqueue.push(Point(x,dis[x]));
}
}
}
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
if(n==0)break;
memset(graph,0,sizeof(graph));
for(int i=0;i<m;i++){
int f,t,d;
scanf("%d%d%d",&f,&t,&d);
graph[f].push_back(Edge(t,d));//视为无向边
graph[t].push_back(Edge(f,d));
}
for(int i=1;i<=n;i++)scanf("%d",&leader[i]);
Dijkstra(1,n);
if(dis[2]==INF)printf("-1\n");
else printf("%d\n",dis[2]);
}
return 0;
}