HDU 6797 Tokitsukaze and Rescue

题目大意

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

题解

发现题目强调了边权随机,容易想到最短路上边的数量应该很少,考虑暴力枚举删边。因此只需每次求一遍最短路,在最短路上选1条边删掉,再往下递归,再求一遍最短路,再选一条边删掉,直至选完 \(k\) 条边,去求得的 \(1\sim 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\n",Ans);
    }
    return 0;
}
posted @ 2020-07-29 10:51  AE酱  阅读(294)  评论(0编辑  收藏  举报