zoukankan      html  css  js  c++  java
  • HDU

    题意: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
    ",d[N]);
        }
        return 0;
    }
    为了更好的明天
  • 相关阅读:
    搜狗输入法——从繁体改成简体
    java官网下载
    eclipse官网下载
    java拷贝指定文件夹下的指定文件类型
    bat脚本——删除当前文件夹的所有指定文件类型
    windows系统下载地址大全&大白菜下载和教程
    struts2——文件下载自定义文件名,包括中文
    struts2——文件下载(简单的功能)
    nginx官网下载&百度云分享
    Apache HTTP Server——官网下载
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9470019.html
Copyright © 2011-2022 走看看