HDU6797:Tokitsukaze and Rescue——题解

http://acm.hdu.edu.cn/showproblem.php?pid=6797

给一个无向完全图,边权随机,求割 $k$ 条边能使得最短路最大。

简单猜测构成最短路的边不会很多。(因为每条边的边范围权一样的,所以如果要构造一条比当前最短路的边多还要短的路径的话对每条边的边权限制就要比之前更严格……虽然具体概率不会算就是了)

那么暴力枚举最短路上的每条边砍掉,然后重新找最短路,然后重复上述过程。

复杂度能过就行。

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef pair<int,int>pii;
const int INF=1e9;
const int N=55;
inline int read(){
    int 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();
    return w?-X:X;
}

int n,m;
int dis[N];
int f[N][N];
priority_queue<pii,vector<pii>,greater<pii> >q;
int dij(int s, int *from){
    for(int i=1;i<=n;i++)dis[i]=INF;
    dis[s]=0;q.push(pii(0,s));
    while(!q.empty()){
        int u=q.top().se,d=q.top().fi;q.pop();
        if(d!=dis[u])continue;
        for(int v=1;v<=n;v++){
            if(u==v)continue;
            int w=f[u][v];
            if(w==INF)continue;
            if(dis[v]>dis[u]+w){
                dis[v]=dis[u]+w;
                from[v]=u;
                q.push(pii(dis[v],v));
            }
        }
    }
    return dis[n];
}
int ans;
void dfs(int k){
    int from[N];
    if(!k){
        ans=max(ans,dij(1,from));
        return;
    }
    dij(1,from);
    int u=n;
    while(u!=1){
        int v=from[u];
        int tmp=f[u][v];
        f[u][v]=f[v][u]=INF;
        dfs(k-1);
        f[u][v]=f[v][u]=tmp;
        u=v;
    }
}
int main(){
    int T=read();
    while(T--){
        n=read(),m=read();
        ans=0;
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                int u=read(),v=read();
                f[u][v]=f[v][u]=read();
            }
        }
        dfs(m);
        printf("%d\n",ans);
    }
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

 +本文作者:luyouqi233。               +

 +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2020-07-28 20:34  luyouqi233  阅读(222)  评论(0编辑  收藏