• 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;
    }
    为了更好的明天
  • 相关阅读:
    nginx + uwsgi 配置参考
    windows 7 下安装VMWARE 和 red-hat 7 64bit
    js jquery select 操作 获取值,选中选项,增加,修改,删除
    css 圆形头像
    css border 三角形
    网页发起qq临时会话
    js 判断字符串中是否包含某个字符串
    jquery 事件的绑定,触发和解绑
    js click 与 onclick 事件绑定,触发与解绑
    jquery 表单序列化
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9470019.html
Copyright © 2020-2023  润新知