HDU 6386 Age of Moyu(最短路变形)

Age of Moyu

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1531    Accepted Submission(s): 467


 

Problem Description

Mr.Quin love fishes so much and Mr.Quin’s city has a nautical system,consisiting of N ports and M shipping lines. The ports are numbered 1 to N. Each line is occupied by a Weitian. Each Weitian has an identification number.

The i-th (1≤i≤M) line connects port Ai and Bi (Ai≠Bi) bidirectionally, and occupied by Ci Weitian (At most one line between two ports).

When Mr.Quin only uses lines that are occupied by the same Weitian, the cost is 1 XiangXiangJi. Whenever Mr.Quin changes to a line that is occupied by a different Weitian from the current line, Mr.Quin is charged an additional cost of 1 XiangXiangJi. In a case where Mr.Quin changed from some Weitian A's line to another Weitian's line changes to Weitian A's line again, the additional cost is incurred again.

Mr.Quin is now at port 1 and wants to travel to port N where live many fishes. Find the minimum required XiangXiangJi (If Mr.Quin can’t travel to port N, print −1instead)

 

Input

There might be multiple test cases, no more than 20. You need to read till the end of input.

For each test case,In the first line, two integers N (2≤N≤100000) and M (0≤M≤200000), representing the number of ports and shipping lines in the city.

In the following m lines, each contain three integers, the first and second representing two ends Ai and Bi of a shipping line (1≤Ai,Bi≤N) and the third representing the identification number Ci (1≤Ci≤1000000) of Weitian who occupies this shipping line.

 

Output

For each test case output the minimum required cost. If Mr.Quin can’t travel to port N, output −1 instead.

 

Sample Input

 

3 3 1 2 1 1 3 2 2 3 1 2 0 3 2 1 2 1 2 3 2

 

Sample Output

 

1 -1 2

题意:给你一个图,每条边有一种颜色。你每走一种颜色消耗1分钟,然后沿该颜色的边继续走就不消耗时间,走其他颜色的边就会再消耗1分钟。求从1点走到n点至少需要几分钟,如果走不到n点输出-1。

思路:就是最短路的变形。虽然这道题好像标程错了还是原题(但是出一道题毕竟不容易)。。。有多种解法,这里我只说我比赛的时候过了的解法。

由于保证全局最优,我们每次只走一步,然后暴力dfs遍历这一步能走到的所有点(这样一定保证1点到每一个点都是最短的)。由于所有边的点都只走一次,保证了时间复杂度不会超过O(n+m)自己xjb乱算的,为了节省时间到达n直接返回。

代码:

#pragma comment(linker,"/STACK:10240000,10240000")
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=400010;
struct node
{
    int id,u,v,cost;
    node(int _id=0,int _u=0,int _v=0,int _cost=0):id(_id),u(_u),v(_v),cost(_cost){}
};
queue<int>q;
vector<node>e[maxn];
int n,m,k;
int dis[maxn],vis[maxn];
void addedge(int id,int u,int v,int w)
{
    e[u].push_back(node(id,u,v,w));
}
void dfs(int x,int id,int dep,int fa)
{
    if(!vis[x]){q.push(x);dis[x]=dep;vis[x]=1;}
    if(dis[n]!=inf)return;
    for(int i=0;i<e[x].size();i++)
    {
        node &k=e[x][i];
        if(k.v==fa||k.id) continue;
        if(k.cost==id)
        {
            k.id=1;
            dfs(k.v,id,dep,x);
            if(dis[n]!=inf)return;
        }
    }
}
int main()
{
    int T,cas=1;
    while(scanf("%d %d",&n,&m)!=EOF){
    for(int i=0;i<=n;i++)
    {dis[i]=inf;e[i].clear();vis[i]=0;}
    while(!q.empty())q.pop();
    int u,v,w;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&u,&v,&w);
        if(u==v) continue;
        addedge(0,u,v,w);
        addedge(0,v,u,w);
    }
    dis[1]=0;q.push(1);vis[1]=1;
    while(!q.empty())
    {
        int k=q.front();q.pop();
        for(int i=0;i<e[k].size();i++)
        {
            node &j=e[k][i];
            if(j.id) continue;
            j.id=1;
            dfs(j.v,j.cost,dis[k]+1,-1);
            if(dis[n]!=inf)break;
        }
        if(dis[n]!=inf) break;
    }
    if(dis[n]==inf) puts("-1");
    else printf("%d\n",dis[n]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/LSD20164388/article/details/81662336