题目描述
The country is facing a terrible civil war----cities in the country are divided into two parts supporting different leaders. As a merchant, Mr. M does not pay attention to politics but he actually knows the severe situation, and your task is to help him reach home as soon as possible. "For the sake of safety,", said Mr.M, "your route should contain at most 1 road which connects two cities of different camp." Would you please tell Mr. M at least how long will it take to reach his sweet home?
输入描述:
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.
示例1
输入
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
此题是POJ的3767号题目,是一个无向图最短的路径问题。
此题的限制在于每个图的结点有一个阵营的限制,且只能跨越一次阵营。题目已经限制起点是1,终点是2,且起点1的阵营是1,终点2的阵营是2.
解决此题的思路还是dijkstra算法,不同的是,在更新最短距离是,不允许出现出现从阵营2到阵营1的情况。
因为可以跨越一次阵营,且起点是1,阵营为1。四种情况里,1-1,1-2,2-2,2-1 只要限制不存在2-1的情况,就不会两次跨越阵营。假设跨越了两次阵营,必然是从1跨到2,再从2跨到1,不满足。
不失一般性的,假设起点和终点不是每次都一样,而是随机给定,而且阵营不定,应该怎么做呢?
如果仍然是最多只能跨越一次阵营,难度差不多:
先记录起点和终点,若两者阵营不同,和上述思路一致;若阵营相同,则只在与两者阵营相同的结点里进行dijkstra算法。
如果继续提升难度,起点终点不定且最多可以跨越两次阵营。(还未想怎么解决)
此题解决代码(没有考虑多组数据,所以不能AC):
#include <iostream>
#define MAX 999999
using namespace std;
int main()
{
int n,m;
int i,j;
int weight;
int origin = 1,dest = 2;
int minPos=0,minWeight=0;
cin>>n>>m;
int map[n+1][n+1]={0}; //邻接矩阵
int s[n+1]={0}; //标记数组
int parts[n+1]; //阵营数组
int dist[n+1]; //距离数组
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j] = MAX;
for(i=0;i<m;i++)
{
int p,q;
cin>>p>>q>>weight;
map[p][q] = weight;
map[q][p] = weight;
}
for(i=1;i<=n;i++)
{
cin>>parts[i];
}
for(i=2;i<=n;i++)
{
if(map[origin][i] == 0)
dist[i] = MAX;
else
dist[i] = map[origin][i];
}
s[1] = 1;
for(i=1;i<=n;i++)
{
minPos = origin;
minWeight = MAX;
for(j=1;j<=n;j++)
{
if( !s[j] && minWeight > dist[j] )
{
minWeight = dist[j];
minPos = j;
}
}
if(minPos == origin)
break;
s[minPos]=1;
for(j=1;j<=n;j++)
{
if(!s[j] && !(parts[minPos]==2 && parts[j] == 1) && dist[j] > dist[minPos] + map[minPos][j] )
{
dist[j] = dist[minPos] + map[minPos][j];
}
}
}
cout<<dist[dest];
return 0;
}