最短路变形题目 HDU多校7

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 (1iM) line connects port Ai and Bi (AiBi) 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 1

instead)
InputThere 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 (2N100000) and M (0M200000), 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 (1Ai,BiN) and the third representing the identification number Ci (1Ci1000000) of Weitian who occupies this shipping line.OutputFor 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

题意 : 给你 n 个点,m 条边,在给你一些两点间的路径值,让你求1 - n的最小花费,当你改变航线以后所消耗的权值就会 + 1;
思路分析 : 就是一个正常的最短路变形题目,但是好卡时限啊, 2449ms ,
    基本就是正常的最短路更新,从一个点更新到另一个点时,同时用set记录一下有哪些状态到达了这个点,一旦可以更新,就清空此集合中的全部元素
代码示例 :
  dij
using namespace std;
#define ll long long
const int maxn = 1e5+5;
const int inf = 0x3f3f3f3f;

int n, m;
struct node
{
    int to, pt, cost, fa;
    bool operator< (const node &v)const{
        return cost > v.cost;
    }
};
priority_queue<node>que;
vector<node>ve[maxn];
bool vis[maxn];
int dis[maxn];
set<int>s[maxn];

void solve(){
    while(!que.empty()) que.pop();
    for(int i = 1; i <= 100000; i++) s[i].clear();
    memset(vis, false, sizeof(vis));
    memset(dis, inf, sizeof(dis));
    que.push({1, 0, 0, 0});
    dis[1] = 0;
    
    while(!que.empty()){
        node v = que.top(); que.pop();
        
        int x = v.to;
        if (v.cost > dis[x]) continue;
        for(int i = 0; i < ve[x].size(); i++){
            int to = ve[x][i].to;
            int pt = ve[x][i].pt;
            if (to == v.fa) continue;
            int cost = 0;
            if (s[x].count(pt) == 0) cost++;
            
            if (dis[x]+cost < dis[to]) {
                dis[to] = dis[x]+cost;
                s[to].clear();
                s[to].insert(pt);
                que.push({to, pt, dis[to], x});
            }
            else if (dis[x]+cost == dis[to] && s[to].count(pt) == 0){
                s[to].insert(pt); 
                que.push({to, pt, dis[to], x});
            }
        }
    }
    if (dis[n] == inf) puts("-1");
    else 
        printf("%d
", dis[n]);
}

int main() {
    int u, v, w;
    
    while(~scanf("%d%d", &n, &m)){
        for(int i = 1; i <= 100000; i++) ve[i].clear();
        for(int i = 1; i <= m; i++){
            scanf("%d%d%d", &u, &v, &w);    
            ve[u].push_back({v, w, 0, 0});            
            ve[v].push_back({u, w, 0, 0});
        }
        solve();
    }
    return 0;
}

spfa

using namespace std;
#define ll long long
const int maxn = 1e5+5;
const int mod = 1e9+7;
const double eps = 1e-9;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;

int n, m;
struct node
{
    int to, pt, fa;
    //bool operator< (const node& v)const{
        //return cost > v.cost;
    //}
};
queue<node>que;
vector<node>ve[maxn];
bool vis[maxn];
int dis[maxn];
set<int>s[maxn];

void solve(){
    while(!que.empty()) que.pop();
    for(int i = 1; i <= 100000; i++) s[i].clear();
    memset(vis, false, sizeof(vis));
    memset(dis, inf, sizeof(dis));
    que.push({1, 0, 0});
    dis[1] = 0; vis[1] = 1;
    
    while(!que.empty()){
        node v = que.front(); que.pop();
        
        int x = v.to;
        vis[x] = 0;
        for(int i = 0; i < ve[x].size(); i++){
            int to = ve[x][i].to;
            int pt = ve[x][i].pt;
            if (to == v.fa) continue;
            int cost = 0;
            if (s[x].count(pt) == 0) cost++;
            
            if (dis[x]+cost < dis[to]) {
                dis[to] = dis[x]+cost;
                s[to].clear();
                s[to].insert(pt);
                if (!vis[to]) {
                    que.push({to, pt, x});
                    vis[to] = 1;
                } 
            }
            else if (dis[x]+cost == dis[to] && s[to].count(pt) == 0){
                s[to].insert(pt);
                //que.push({to, pt, dis[to], x});
                if (!vis[to]) {
                    que.push({to, pt, x});
                    vis[to] = 1;
                }
            }
        }
    }
    if (dis[n] == inf) puts("-1");
    else 
        printf("%d
", dis[n]);
}

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int u, v, w;
    
    while(~scanf("%d%d", &n, &m)){
        for(int i = 1; i <= 100000; i++) ve[i].clear();
        for(int i = 1; i <= m; i++){
            scanf("%d%d%d", &u, &v, &w);    
            ve[u].push_back({v, w, 0});            
            ve[v].push_back({u, w, 0});
        }
        solve();
    }
    return 0;
}
东北日出西边雨 道是无情却有情
原文地址:https://www.cnblogs.com/ccut-ry/p/9808073.html