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
at city 1, and Voldemort is located at city n. To make the world peace as soon
as possible, Of course, Harry Potter will choose the shortest road between city
1 and city n. But unfortunately, Voldemort is so powerful that he can choose to
destroy any one of the existing roads as he wish, but he can only destroy one.
Now given the roads between cities, you are to give the shortest time that Harry
Potter can reach city n and begin the battle in the worst case.

Input

First line, case number t (t<=20).
Then for each
case: an integer n (2<=n<=1000) means the number of city in the magical
world, the cities are numbered from 1 to n. Then an integer m means the roads in
the magical world, m (0< m <=50000). Following m lines, each line with
three integer u, v, w (u != v,1 <=u, v<=n, 1<=w <1000), separated by
a single space. It means there is a bidirectional road between u and v with the
cost of time w. There may be multiple roads between two cities.

Output

Each case per line: the shortest time to reach city n
in the worst case. If it is impossible to reach city n in the worst case, output
“-1”.

Sample Input

3

4

4

1 2 5

2 4 10

1 3 3

3 4 8

3

2

1 2 5

2 3 10

2

2

1 2 1

1 2 2

Sample Output

15

-1

2

Author

[email protected]

Source

2011
Multi-University Training Contest 15 - Host by WHU

题意:一个无向图,n个点,m条边,输入m条边的起点,终点,距离,假设减去其中任意一条边,问各种情况下的最短路中最长的是哪条,可能有重边。

这题和1595非常像,但是因为可能有重边(删去一边边,还是可以走另一条路的情况),所以必须使用邻接表写。

附上代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <queue>
  5 #define N 1005
  6 #define M 50005
  7 #define INF 0x3f3f3f3f
  8 using namespace std;
  9
 10 struct Edge
 11 {
 12     int from,to,val;
 13     int next;
 14     bool used;
 15 } edge[M*2];
 16
 17 int n,m,tol;
 18 int head[M*2],dis[N];
 19 bool vis[N];
 20 int flag;
 21 int path[N];
 22
 23 void init()
 24 {
 25     tol=0;
 26     flag=0;
 27     memset(head,-1,sizeof(head));
 28     memset(path,-1,sizeof(path));
 29 }
 30
 31 void addEdge(int u,int v,int val)
 32 {
 33     edge[tol].from=u;
 34     edge[tol].to=v;
 35     edge[tol].val=val;
 36     edge[tol].used=true;
 37     edge[tol].next=head[u];
 38     head[u]=tol++;
 39     edge[tol].from=v;
 40     edge[tol].to=u;
 41     edge[tol].val=val;
 42     edge[tol].used=true;
 43     edge[tol].next=head[v];
 44     head[v]=tol++;
 45 }
 46
 47 void getmap()
 48 {
 49     scanf("%d%d",&n,&m);
 50     int a,b,c;
 51     while(m--)
 52     {
 53         scanf("%d%d%d",&a,&b,&c);
 54         addEdge(a,b,c);
 55     }
 56 }
 57
 58 int spfa()
 59 {
 60     memset(dis,INF,sizeof(dis));
 61     memset(vis,false,sizeof(vis));
 62     queue<int>q;
 63     q.push(1);
 64     dis[1]=0;
 65     vis[1]=true;
 66     while(!q.empty())
 67     {
 68         int u=q.front();
 69         q.pop();
 70         vis[u]=false;
 71         for(int i=head[u]; i!=-1; i=edge[i].next)
 72         {
 73             int v=edge[i].to;
 74             if(edge[i].used)
 75                 if(dis[v]>dis[u]+edge[i].val)
 76                 {
 77                     dis[v]=dis[u]+edge[i].val;
 78                     if(!flag)
 79                         path[v]=i;   ///记录可以缩进的边,这些边可以改变总路程
 80                     if(!vis[v])
 81                     {
 82                         vis[v]=true;
 83                         q.push(v);
 84                     }
 85                 }
 86         }
 87     }
 88     return dis[n];
 89 }
 90
 91 void newmap()
 92 {
 93     int i=n,j=-1;
 94     int ans=-1;
 95     while(path[i]!=-1)
 96     {
 97         j=path[i];
 98         edge[j].used=edge[j+1].used=false;
 99         int tmp=spfa();
100         edge[j].used=edge[j+1].used=true;
101         if(tmp>ans)
102             ans=tmp;
103         i=edge[j].from;
104     }
105     if(ans<INF)
106         printf("%d\n",ans);
107     else
108         printf("-1\n");
109 }
110
111 int main()
112 {
113     int T;
114     scanf("%d",&T);
115     while(T--)
116     {
117         init();
118         getmap();
119         spfa();
120         newmap();
121     }
122 }
时间: 2024-10-14 04:32:19

hdu 3986 Harry Potter and the Final Battle的相关文章

【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 有多重边,用邻接矩阵不方便,用邻接表方便,

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 3988 Harry Potter and the Hide Story(数论-整数和素数)

Harry Potter and the Hide Story Problem Description iSea is tired of writing the story of Harry Potter, so, lucky you, solving the following problem is enough. Input The first line contains a single integer T, indicating the number of test cases. Eac

hdu 3987 Harry Potter and the Forbidden Forest 求割边最少的最小割

view code//hdu 3987 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; typedef long long ll; const ll INF = 1LL<<59; const ll E = 100001; const int N = 10

hdu:4771Stealing Harry Potter&#39;s Precious(bfs + 全排列)

题目:hdu:4771Stealing Harry Potter's Precious 题目大意:给出n* m的矩阵,代表n * m间room,然后每个房间又有脆弱和坚固之分,分别用'.'和'#'代替.'@'代表Dudely所在的起点. 题目说Dudely想要偷Harry的宝物,他知道宝物的位置,但是他的魔法只能穿过脆弱的room.愚蠢的他又想偷完harry所有的宝物,并不在乎如何人出去.问最短移动的步数偷完所有的宝物.没法偷完所有的宝物就输出-1. 解题思路:这里要求的是最短路径问题.可以将各

hdu 3987 Harry Potter and the Forbidden Forest【网路流最小割模型】

Harry Potter and the Forbidden Forest Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1549    Accepted Submission(s): 528 Problem Description Harry Potter notices some Death Eaters try to slip

HDU 3987 Harry Potter and the Forbidden Forest(最小割中的最少割边)经典

Harry Potter and the Forbidden Forest Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1791    Accepted Submission(s): 596 Problem Description Harry Potter notices some Death Eaters try to slip