zoukankan      html  css  js  c++  java
  • HDU 6797 Tokitsukaze and Rescue

    题目大意

    给你一个 (n(3leq nleq 50)) 个点的完全图,每条边都有边权,且边权为 ([1,10^4]) 范围内的随机数,要求删掉 (k(1leq kleq min(n-2,5))) 条边,使得 (1sim n) 的最短路最长,输出删去 (k) 条边后最长的最短路。

    题解

    发现题目强调了边权随机,容易想到最短路上边的数量应该很少,考虑暴力枚举删边。因此只需每次求一遍最短路,在最短路上选1条边删掉,再往下递归,再求一遍最短路,再选一条边删掉,直至选完 (k) 条边,去求得的 (1sim n) 所有最短路中的最大值即可。

    Code

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #include <vector>
    #include <queue>
    using namespace std;
    
    #define RG register int
    #define LL long long
    
    template<typename elemType>
    inline void Read(elemType &T){
        elemType X=0,w=0; char ch=0;
        while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
        while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        T=(w?-X:X);
    }
    
    int Dis[51],G[51][51];
    bool Mark[51][51];
    int T,N,K,Ans;
    
    const int INF=0x7fffffff;
    struct Node{int Value,ID;};
    struct cmpA{bool operator()(Node A,Node B){return A.Value>B.Value;}};
    priority_queue<Node,vector<Node>,cmpA> Q;
    bool vis[51];
    
    int Dijkstra(int st){
        memset(Dis,0x3f,sizeof(Dis));
        memset(vis,0,sizeof(vis));
        Dis[st]=0;Q.push((Node){0,st});
        while(!Q.empty()){
            int u=Q.top().ID;Q.pop();
            if(vis[u]) continue;
            vis[u]=true;
            for(RG v=1;v<=N;++v){
                if(Mark[u][v]||vis[v]) continue;
                if(Dis[v]>Dis[u]+G[u][v]){
                    Dis[v]=Dis[u]+G[u][v];
                    Q.push((Node){Dis[v],v});
                }
            }
        }
        return Dis[N];
    }
    
    struct edge{int u,v;};
    edge E[6][100];
    int Que[2000],head,tail;
    
    inline void Get_Path(int &cnt,int num){
        head=1;tail=0;
        Que[++tail]=N;
        while(tail>=head){
            int u=Que[head];++head;
            for(RG v=1;v<=N;++v){
                if(v==u||Mark[v][u]) continue;
                if(Dis[v]+G[v][u]==Dis[u]){
                    Que[++tail]=v;++cnt;
                    E[num][cnt].u=u;E[num][cnt].v=v;
                }
            }
        }
        return;
    }
    
    void DFS(int num){
        Ans=max(Ans,Dijkstra(1));
        if(num==K) return;
        int cnt=0;Get_Path(cnt,num);
        for(RG i=1;i<=cnt;++i){
            int u=E[num][i].u,v=E[num][i].v;
            Mark[u][v]=Mark[v][u]=true;
            DFS(num+1);
            Mark[u][v]=Mark[v][u]=false;
        }
        return;
    }
    
    int main(){
        Read(T);
        while(T--){
            Read(N);Read(K);
            for(RG i=1;i<=N*(N-1)/2;++i){
                int u,v,w;
                Read(u);Read(v);Read(w);
                G[u][v]=G[v][u]=w;
            }
            Ans=Dijkstra(1);
            DFS(0);
            printf("%d
    ",Ans);
        }
        return 0;
    }
    
  • 相关阅读:
    力扣516题、72题、1312题(最长回文子序列,编辑距离,构造回文串)
    力扣53题、1143题(最大子数组问题、最长公共子序列)
    力扣704题、34题(二分查找)
    力扣300题、354题(最长递增子序列,信封嵌套)
    力扣509题、70题(斐波那契数列、爬楼梯)
    力扣206题、92题、25题(反转链表)
    力扣234题(回文链表)
    力扣239题(单调队列)
    力扣496题、503题(单调栈)
    面试题简答题
  • 原文地址:https://www.cnblogs.com/AEMShana/p/13395799.html
Copyright © 2011-2022 走看看