题目描述
输入描述:
The input contains multiple test cases. The first line of each case is an integer N (2<=N<=600), representing the number of cities in the country. The second line contains one integer M (0<=M<=10000), which is the number of roads. The following M lines are the information of the roads. Each line contains three integers A, B and T, which means the road between city A and city B will cost time T. T is in the range of [1,500]. Next part contains N integers, which are either 1 or 2. The i-th integer shows the supporting leader of city i. To simplify the problem, we assume that Mr. M starts from city 1 and his target is city 2. City 1 always supports leader 1 while city 2 is at the same side of leader 2. Note that all roads are bidirectional and there is at most 1 road between two cities. Input is ended with a case of N=0.
输出描述:
For each test case, output one integer representing the minimum time to reach home. If it is impossible to reach home according to Mr. M's demands, output -1 instead.
输入
2 1 1 2 100 1 2 3 3 1 2 100 1 3 40 2 3 50 1 2 1 5 5 3 1 200 5 3 150 2 5 160 4 3 170 4 2 170 1 2 2 2 1 0
输出
100 90 540
//最短路径算法,通常情况下考察最短路径都会考察改进版。
//此题某人只能从1所领导的城市到2所了领导的城市,我们可以设置标记
#include<iostream>
#include<vector>
using namespace std;
struct E
{
int next;//一个存储相邻的结点
int cost;//存储边的权值
};
vector<E>edges[10001];
int dis[700];
int leader[700];
bool mark[701];//标记某顶点是否在最短路径顶点集合当中
int newp;
int main()
{
int n,m;
while(cin>>n>>m)
{
if(n==0)break;
for(int i=1;i<=n;i++)
{
edges[i].clear();//每一个结点保存着其相邻的边
mark[i]=false;
dis[i]=-1;
}
for(int i=1;i<=m;i++)
{
E n;
int a,b,cost;
cin>>a>>b>>cost;
n.next=b;
n.cost=cost;
edges[a].push_back(n);
n.next=a;
edges[b].push_back(n);
}//这段是建立无向图的,任意一条边连接着两个顶点
for(int i=1;i<=n;i++)
cin>>leader[i];
mark[1]=true;
newp=1;
dis[1]=0;//存储的权值(到第一个点权值和)
for(int i=1;i<n;i++)//除了最后一个点
{
for(int j=0;j<edges[newp].size();j++)
{
int t=edges[newp][j].next;
int c=edges[newp][j].cost;
if(mark[t]==true)continue;//已经在路径集合当中
if(leader[t]==1&&leader[newp]==2)continue;
if(dis[t]==-1||dis[t]>c+dis[newp])
{
dis[t]=dis[newp]+c;
}
}//找到newp到其每个相邻点的权值
//求权值最小值并将那个点置为newp
int minn=10000;
for(int j=1;j<=n;j++)
{
if(mark[j])continue;
if(dis[j]==-1)continue;
if(minn>dis[j])
{
minn=dis[j];
newp=j;
}
}
mark[newp]=true;
}
cout<<dis[2]<<endl;
}
return 0;
}