HDU 6797 Tokitsukaze and Rescue
阿新 • • 發佈:2020-07-29
題目大意
給你一個 \(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; }