1. 程式人生 > 實用技巧 >HDU6797:Tokitsukaze and Rescue——題解

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/+

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