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