略水。。
题目大意是 有n个城市,要从 第1个城市 走到 第2个城市的最短路。。(起点是1, 终点是2),但是,每个城市都属于不同的领主。。
"For the sake of safety,", said Mr.M, "your route should contain at most 1 road which connects two cities of different camp.
要求你走的最短路中, 最多包含1条连接两个城市但却属于不同的领主的路。。
dijkstra算法,+多一个sum[]数组记录 有多少条连接两个城市但却属于不同的领主的路。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
#define eps 1e-8
#define mod 1000000007
#define mnx 20005
#define ll long long
#define ull unsigned long long
#define inf 0x3f3f3f3f
int cost[mnx], first[mnx], vv[mnx], nxt[mnx], dis[mnx], lead[mnx], sum[mnx], e, m, n;
bool vis[mnx];
struct edge{
int u, d;
bool operator < (const edge &b) const {
return d > b.d;
}
};
void init(){
memset(dis, 0x3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
memset(first, -1, sizeof(first));
memset(sum, 0, sizeof(sum));
e = 0;
}
void add( int u, int v, int c ){
cost[e] = c;
vv[e] = v;
nxt[e] = first[u];
first[u] = e++;
}
void dijkstra(int s){
priority_queue<edge> que;
dis[s] = 0;
edge q1; q1.u = s; q1.d = 0;
que.push(q1);
while( !que.empty() ){
q1 = que.top(); que.pop();
int u = q1.u;
if( vis[u] ) continue;
vis[u] = 1;
for( int i = first[u]; i != -1; i = nxt[i] ){
int v = vv[i];
if( dis[v] > dis[u] + cost[i] ){
if(lead[u] == lead[v] || (lead[u] != lead[v] && sum[u] + 1 < 2) ) { //注意条件。。
if( lead[u] != lead[v] ) sum[v] = sum[u] + 1;
else sum[v] = sum[u];
dis[v] = dis[u] + cost[i];
edge q2;
q2.d = dis[v], q2.u = v;
que.push(q2);
}
}
}
}
}
int main(){
while( scanf("%d", &n) && n ){
init();
scanf("%d", &m);
int u, v, d;
for( int i = 0; i < m; i++ ){
scanf("%d%d%d", &u, &v, &d);
add(u, v, d);
add(v, u, d);
}
for( int i = 1; i <= n; i++ ){
scanf("%d", &lead[i]);
}
dijkstra(1);
if( dis[2] >= inf ) printf("-1\n");
else printf("%d\n", dis[2]);
}
return 0;
}