HDU多校3 - 6797 Tokitsukaze and Rescue(dfs+最短路)
生活随笔
收集整理的這篇文章主要介紹了
HDU多校3 - 6797 Tokitsukaze and Rescue(dfs+最短路)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出一張無向完全圖,現在要求刪除 k 條邊,問刪除后的最短路的最大值是多少,k 最大是 5
題目分析:很玄學的一道題,數據范圍非常小且時間給了 8 秒,比賽時我直接暴力貪心,每次 tarjan 直接找最短路的必經邊然后刪除,但過了樣例卻返回了 WA ,然后就自閉了,看了題解之后真的感覺非常奇妙
讀完題后就注意到題目中說了所有的邊權均是隨機數,題解說因為隨機數的期望都是一樣的,最短路求出后每次只有一條,且涉及到的邊數非常少,其他的反例的幾率非常非常小,這樣可以對每一層進行爆搜,時間復雜度為 c^k * n^2,c 為最短路的邊數
然后實現就好了,注意要用樸素的 n * n 的迪杰斯特拉而不是堆優化的,因為堆優化的時間復雜度為 ( n + m ) * logm ,在這個題中顯然不如 n * n 的要表現優秀
至于找最短路上的邊,我是參考了 std 記錄每個點的前驅來實現的,換句話說每次最短路有且僅有一條(不會證明),當然也可以正反各求一次最短路,然后 n * n 去枚舉每條邊判斷是否位于最短路上,不知道會不會超時
代碼:
#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<unordered_map> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=55;int maze[N][N],pre[6][N],d[N],ans,n;bool vis[N];void Dijkstra(int k) {memset(d,inf,sizeof(int)*(n+5));memset(vis,false,n+5);d[1]=0;for(int i=1;i<n;i++){int mmin=inf,u=-1;for(int j=1;j<=n;j++)if(!vis[j]&&d[j]<mmin){mmin=d[j];u=j;}vis[u]=true;for(int v=1;v<=n;v++)if(d[v]>d[u]+maze[u][v]){d[v]=d[u]+maze[u][v];pre[k][v]=u;}} }void dfs(int k) {Dijkstra(k);if(!k){ans=max(ans,d[n]);return;}int pos=n;while(pos!=1){int u=pos,v=pre[k][pos];int temp=maze[u][v];maze[u][v]=maze[v][u]=inf;dfs(k-1);maze[u][v]=maze[v][u]=temp;pos=pre[k][pos];} }int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int w;cin>>w;while(w--){int k;scanf("%d%d",&n,&k);for(int i=1;i<=n*(n-1)/2;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);maze[u][v]=maze[v][u]=w;}ans=0;dfs(k);printf("%d\n",ans);}return 0; }?
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的HDU多校3 - 6797 Tokitsukaze and Rescue(dfs+最短路)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 牛客多校6 - Binary Vecto
- 下一篇: HDU多校3 - 6798 Triang