【Dijstra堆优化】HDU 3986 Harry Potter and the Final Battle

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

【题意】

  • 给定一个有重边的无向图,T=20,n<=1000,m<=5000
  • 删去一条边,使得1~n的最短路最长
  • 求最短路最长是多少

【思路】

  • 一定是删最短路上的边
  • 可以先跑一个Dijkstra,求出最短路,然n后枚举删边
  • 朴素的Dijkstra为n^2,枚举删边(n条)需要的总时间复杂度是n^3
  • 堆优化Dijkstra(nlogn),总复杂度为n^2logn
  • 有多重边,用邻接矩阵不方便,用邻接表方便,删去的边标记一下就好

【Accepted】

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<string>
  6 #include<algorithm>
  7 #include<queue>
  8 #include<vector>
  9
 10 using namespace std;
 11 typedef long long ll;
 12 const int maxm=5e4*2+2;
 13 const int maxn=1e3+2;
 14 const int inf=0x3f3f3f3f;
 15 int n,m;
 16 struct node
 17 {
 18     int to;
 19     int nxt;
 20     int w;
 21 }e[maxm];
 22 int head[maxn];
 23 int tot;
 24 bool vis[maxn];
 25 int dis[maxn];
 26 int pv[maxn];
 27 int pe[maxn];
 28 typedef pair<int,int> pii;
 29 void init()
 30 {
 31     memset(head,-1,sizeof(head));
 32     tot=0;
 33 }
 34
 35 void add(int u,int v,int w)
 36 {
 37     e[tot].to=v;
 38     e[tot].w=w;
 39     e[tot].nxt=head[u];
 40     head[u]=tot++;
 41 }
 42
 43 int Dij(int x)
 44 {
 45     priority_queue<pii,vector<pii>,greater<pii> >pq;
 46     memset(vis,false,sizeof(vis));
 47     memset(dis,inf,sizeof(dis));
 48     dis[1]=0;
 49     pq.push(make_pair(dis[1],1));
 50 //    pq.push(pii(dis[1],1));
 51     while(!pq.empty())
 52     {
 53         pii cur=pq.top();
 54         pq.pop();
 55         int u=cur.second;
 56         if(vis[u]) continue;
 57         vis[u]=true;
 58         for(int i=head[u];i!=-1;i=e[i].nxt)
 59         {
 60             if(i==x) continue;
 61             int w=e[i].w;
 62             int v=e[i].to;
 63             if(dis[u]+w<dis[v])
 64             {
 65                 dis[v]=dis[u]+w;
 66                 pq.push(make_pair(dis[v],v));
 67                 if(x==-1)
 68                 {
 69                     pv[v]=u;
 70                     pe[v]=i;
 71                 }
 72             }
 73         }
 74     }
 75     return dis[n];
 76 }
 77
 78 int Solve()
 79 {
 80     if(Dij(-1)==inf)
 81     {
 82         return -1;
 83     }
 84     int ans=0;
 85     for(int i=n;i!=1;i=pv[i])
 86     {
 87         ans=max(ans,Dij(pe[i]));
 88         if(ans==inf)
 89         {
 90             return -1;
 91         }
 92     }
 93     return ans;
 94 }
 95 int main()
 96 {
 97     int T;
 98     scanf("%d",&T);
 99     while(T--)
100     {
101         init();
102         scanf("%d%d",&n,&m);
103         while(m--)
104         {
105             int u,v,w;
106             scanf("%d%d%d",&u,&v,&w);
107             add(u,v,w);
108             add(v,u,w);
109         }
110         int ans=Solve();
111         printf("%d\n",ans);
112     }
113     return 0;
114 }

堆优化的Dijkstra

时间: 2024-10-26 20:34:36

【Dijstra堆优化】HDU 3986 Harry Potter and the Final Battle的相关文章

hdu 3986 Harry Potter and the Final Battle

Harry Potter and the Final Battle Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 3319    Accepted Submission(s): 936 Problem Description The final battle is coming. Now Harry Potter is located

hdu 3986 Harry Potter and the Final Battle spfa变形

#include<stdio.h> #include<string.h> #include<queue> #include<vector> using namespace std; const int N=1024; const int inf=0x7fffffff; struct Edge { int u,v,w,use,del; }; vector<Edge>edge; vector<int>G[N]; int n,m,dist[

HDU3986Harry Potter and the Final Battle(SPFA册边)

Harry Potter and the Final Battle Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2666    Accepted Submission(s): 761 Problem Description The final battle is coming. Now Harry Potter is located

hdu3986Harry Potter and the Final Battle

给你一个无向图,然后找出其中的最短路, 除去最短路中的任意一条边,看最糟糕的情况下, 新的图中,第一个点到末点的最短路长度是多少. 我的做法是: 首先找出最短路,然后记录路径, 再一条一条边的删, 删一条算一下最短路长度, 之后恢复这条边,删掉下一条边继续算, 以此类推. 看之中最糟糕的情况下,最短路长度是多少, 如果是无穷大则代表最坏情况为不通,按题意输出-1即可, 否则输出最坏情况下,最短路长度. 我用spfa和链式向前星做的, 代码如下: #include<iostream> #incl

HDU-6290_奢侈的旅行(Dijstra+堆优化)

奢侈的旅行 Time Limit: 14000/7000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others) Problem Description 高玩小Q不仅喜欢玩寻宝游戏,还喜欢一款升级养成类游戏.在这个游戏的世界地图中一共有n个城镇,编号依次为1到n. 这些城镇之间有m条单向道路,第i 条单项道路包含四个参数ui,vi,ai,bi,表示一条从ui号城镇出发,在vi号城镇结束的单向道路,因为是单向道路,这不意味着小Q可以

hdu 2066 Dijstra 堆优化

嗯 有广搜的意思 #include<cstdio> #include<iostream> #include<queue> #include<vector> #define maxn 1001 #define inf 9999999 using namespace std; struct vec //这里用邻接矩阵的方式比较浪费空间 所以用邻接表 这里是带权图 所以用结构体构图 { int point,cost; friend bool operator<

复习最短路 spfa+dijstra堆优化

题目很简单,, 但是wa了三次,, 用<vector>之前一定要记得clear()...简单说下 spfa的问题 和bell_forman有点类似 每次取出一个点 然后更新 并把更新了的节点入队(更新的值可能会影响到最优解) 当队列为空的时候算法结束(无法优化)这里的vis数组是为了防止重复入队 但每个节点可能多次入队 所以在拿出来的时候 vis标记要消去最后说下负环的问题 引用一下 对于不存在负权回路的图来说,上述算法是一定会结束的.因为算法在反复优化各个最短路径长度,总有一个时刻会进入&q

hdu 2544 单源最短路问题 dijkstra+堆优化模板

最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 41168    Accepted Submission(s): 17992 Problem Description 在每年的校赛里.全部进入决赛的同学都会获得一件非常美丽的t-shirt.可是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的.所以如今他们想要寻

HDU 4284 状压dp+spfa堆优化

题意: 给定n个点 m条无向边 d元. 下面m行表示每条边 u<=>v 以及花费 w 下面top 下面top行 num c d 表示点标为num的城市 工资为c 健康证价格为d 目标是经过给定的top个城市,当到达该城市时,必须马上购买该城市的健康证并打工赚钱(每个城市只打工1次) 问从1城市出发,最后回到1城市,能否收集到所有的健康证 思路: 由于top很小,所以状压dp dp[i][tmp]表示当前处于i点 经过城市的状态为tmp时 身上最多的钱. 首先对dis数组floyd 跑出最短路,