最短路变形题目 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\n", 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\n", 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值