HDU - 6386 Age of Moyu 2018 Multi-University Training Contest 7 (Dijkstra变型)

题意:N个点M条边的无向图,每条边都有属于自己的编号,如果一条路径上的边编号都相同,那么花费仅为1;改变至不同编号的路径,花费加1,无论这个编号之前是否走过。

分析:记录每个点的最小花费,再用set维护这个最小花费对应的前驱边的编号,可能有多个不同的前驱编号。如果当前状态可以更新点最小花费,那么将set清空并加入前驱编号;如果与最小花费相等且前驱的编号不在集合中,那么将前驱的状态加入集合中。

*BFS要用优先队列,否则会错。

#include<bits/stdc++.h>
using namespace std;
const int maxn =1e5+5;
const int INF = 0x3f3f3f3f;
struct Edge{
    int v,id,next;
}edges[maxn<<2];
int head[maxn],tot;
int d[maxn];
set<int> sta[maxn];

void init()
{
    tot=0;
    memset(head,-1,sizeof(head));
}

void AddEdge(int u,int v,int id)
{
    edges[tot] = (Edge){v,id,head[u]};
    head[u] = tot++;
}

struct Node{
    int val,u;
    int pre,fa;
    bool operator <(const Node &p) const{return val>p.val;}
};
void BFS(int s,int t)
{
    memset(d,INF,sizeof(d));
    d[s] = 0;
    priority_queue<Node> Q;
    Q.push((Node){d[s],s,-1,-1});
    while(!Q.empty()){
        Node x=  Q.top();Q.pop();
        int pre = x.pre, u = x.u;
        if(x.val> d[u]) continue;
        else if(x.val==d[u]){
            bool tag = true;
            if(sta[u].find(pre)!=sta[u].end())
                continue;
            sta[u].insert(pre);
        }
        else{
            d[u] = x.val;
            sta[u].clear();
            sta[u].insert(pre);
        }

        for(int i=head[u];~i;i=edges[i].next){
            int v = edges[i].v,now = edges[i].id;
            if(v==x.fa) continue;                       //反向边
            if((d[u]+(pre!=now))<=d[v]){
                d[v] = d[u] + (pre!=now);
                if(v!=t) Q.push((Node){d[v],v,now,x.u});
            }
        }
    }
}

int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    int N,M;
    int u,v,id;
    while(scanf("%d%d",&N,&M)==2){
        for(int i=1;i<=N;++i) sta[i].clear();
        init();
        while(M--){
            scanf("%d%d%d",&u,&v,&id);
            AddEdge(u,v,id);
            AddEdge(v,u,id);
        }
        BFS(1,N);
        if(d[N]==INF) d[N]=-1;
        printf("%d\n",d[N]);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/xiuwenli/p/9470019.html

时间: 2024-10-24 10:16:26

HDU - 6386 Age of Moyu 2018 Multi-University Training Contest 7 (Dijkstra变型)的相关文章

HDU 4906 Our happy ending(2014 Multi-University Training Contest 4)

题意:构造出n个数 这n个数取值范围0-L,这n个数中存在取一些数之和等于k,则这样称为一种方法.给定n,k,L,求方案数. 思路:装压 每位 第1为表示这种方案能不能构成1(1表示能0表示不能)  第2为表示能不能构成2 ...  这样用d[1<<n] 的DP  像背包那样背 n次就可以 最后状态中第k位为1的就可以加上方法数. #include<cstring> #include<cstdio> #include<cmath> #include <

HDU 4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)

题意:给定n*m个格子,每个格子能填0-k 的整数.然后给出每列之和和每行之和,问有没有解,有的话是不是唯一解,是唯一解输出方案. 思路:网络流,一共 n+m+2个点   源点 到行连流量为 所给的 当前行之和.    每行 连到每一列 一条流量为  k的边,每列到汇点连 列和.如果流量等于总和则有解,反之无解(如果列总和不等于行总和也无解).  判断方案是否唯一 找残留网络是否存在长度大于2的环即可,有环说明不唯一. #include<cstdio> #include<cstring&

hdu 5792 World is Exploding(2016 Multi-University Training Contest 5——树状数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5792 World is Exploding Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 643    Accepted Submission(s): 306 Problem Description Given a sequence A

hdu 5774 Where Amazing Happens(2016 Multi-University Training Contest 4——打表)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5774 Where Amazing Happens Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 443    Accepted Submission(s): 300 Problem Description As the premier m

hdu 6665 Calabash and Landlord (2019 Multi-University Training Contest 8 1009)(离散化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6665 题目大意:给定四个点分别为两个矩形的左上角和右下角,两个矩形与坐标轴平行,问坐标平面(含负轴,但矩形只在第一象限内,部分边可能在正轴上)被两个矩形划分为几个区域(原意问的是几个连通点集但因为是实数点所以相当于问的是区域). 思路:如题,离散化.可以看到点坐标的值可能非常大,但是注意求的只是区域个数,而并不用求每个区域内点的个数,所以我们想要的信息只有点和点之间的位置关系,这时候最简单的方法,就

2018 Nowcoder Multi-University Training Contest 2

Practice Link A. run 题意: 白云每次可以移动\(1\)米或者\(k\)米,询问移动的米数在\([L, R]\)范围内的方案数有多少. 思路: \(dp[i][2]\)表示到第\(i\)米,是通过\(1\)米的方式过来的还是\(k\)米的方式过来的,递推即可. 代码: #include <bits/stdc++.h> using namespace std; #define N 100010 const int p = 1e9 + 7; int f[N][2], g[N];

2018 Nowcoder Multi-University Training Contest 1

Practice Link J. Different Integers 题意: 给出\(n\)个数,每次询问\((l_i, r_i)\),表示\(a_1, \cdots, a_i, a_j, \cdots, a_n\)中有多少个不同的数. 思路: 先分别离线求出\(a_1, \cdots a_i\)以及\(a_j, \cdots, a_n\)中有多少个不同的数. 再考虑有多少个数既在\([1, i]\)中也在\([j, n]\)中,再离线做一次. 考虑一个数第一次出现的时候,那么这个数下一次出现

2018 Nowcoder Multi-University Training Contest 5

Practice Link A. gpa 题意: 有\(n\)门课程,每门课程的学分为\(s_i\),绩点为\(c_i\),要求最多删除\(k\)门课程,使得gpa最高. gpa计算方式如下: \[ \begin{eqnarray*} gpa = \frac{\sum s_ic_i}{\sum s_i} \end{eqnarray*} \] 思路: 首先删去的课程越多,gpa肯定不会变得更差. 所以我们肯定是删去\(k\)门课程. 考虑二分答案,check的时候要满足: \[ \begin{eq

HDU 2018 Multi-University Training Contest 3 Problem A. Ascending Rating 【单调队列优化】

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6319 Problem A. Ascending Rating Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 5943    Accepted Submission(s): 2004 Problem Description Before