九度 OJ1162 I wanna go home

九度 OJ1162 I wanna go home

时间限制:1 秒 内存限制:32 兆 特殊判题:否

1.题目描述:

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

2.基本思路

该题仍然属於单源最短路径的问题,可以利用Dijkstra算法进行求解,当这里加了一个限定,就是Mr.M只能跨越两个阵营一次,那么试想一下。Mr.M需要从City1到达City2,而City1属于1阵营,City2属于2阵营,那么也就是所Mr.M必须要从1阵营到达2阵一次而且只能一次,那么其实我们只要把所有的从2阵营到1阵营的路给封死,那么Mr.M就没有办法从2阵营回到1阵营,那么他有一次从1阵营到2阵营的跨越,符合题目的要求。那么怎么做了,其实只需要在一开始的时候对图的初始化进行适当的调整即可,首先同样是把它初始化为一个无向图(即每一条边上两个方向的通行是等价的),随后遍历所有从2阵营到1阵营的路,把这些路都去掉即可,最后再在改图上利用Dijkstra算法进行求解即可。

注:由于2N6002≤N≤600所以该题不能采用Floyd算法进行求解,因为其时间复杂度为O(n3)O(n^3)

3.代码实现

#include <iostream>
#include <vector>
#include <climits>
#define N 601

using namespace std;

struct E{
    int next;
    int time;
};

vector<E> Map[N];
bool mark[N];
int Dis[N];
int leader[N];
int inf=123123123;

int main()
{
    int n,m;
    while(~scanf("%d",&n)){
        if(n==0)break;
        scanf("%d",&m);
        for(int i=1;i<=n;i++){
            mark[i]=false;
            Dis[i]=inf;
            Map[i].clear();
        }
        int a,b,t;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&a,&b,&t);
            E tmp;
            tmp.next=b;
            tmp.time=t;
            Map[a].push_back(tmp);
            tmp.next=a;
            Map[b].push_back(tmp);
        }

        for(int i=1;i<=n;i++){
            scanf("%d",&leader[i]);
        }
        //处理2->1的路径
        for(int i=1;i<=n;i++){
            if(leader[i]==2){
                for(int j=0;j<Map[i].size();j++){
                    if(leader[Map[i][j].next]==1){
                        Map[i][j].time=inf;
                    }
                }
            }
        }

        int newP=1;
        mark[1]=true;
        Dis[1]=0;

        for(int i=1;i<=n-1;i++){//查找剩余的n-1个最近点
            for(int j=0;j<Map[newP].size();j++){
                int t = Map[newP][j].next;
                int time = Map[newP][j].time;
                if(mark[t])continue;
                if(Dis[t]==inf||Dis[t]>Dis[newP]+time){
                    Dis[t]=Dis[newP]+time;
                }
            }
            int min = INT_MAX;
            for(int i=1;i<=n;i++){
                if(mark[i])
                    continue;
                if(Dis[i]<min){
                    min=Dis[i];
                    newP = i;
                }
            }
            mark[newP]=true;
        }
        if(Dis[2]==inf)
            printf("%d\n",-1);
        else
            printf("%d\n",Dis[2]);


    }
    return 0;
}
/*
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
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章