hdu 1595 find the longest of the shortest

简介: 点击打开链接hdu 1595 思路:最短路+优先队列+Dijstra+枚举边 分析: 1 题目要求的是删掉一条边之和求出的最短路中的最大值。

点击打开链接hdu 1595


思路:最短路+优先队列+Dijstra+枚举边

分析:
1 题目要求的是删掉一条边之和求出的最短路中的最大值。
2 很明显,肯定是要先求出原图的最短路并且记录父亲节点。现在我们可以想,如果要枚举所有的边,显然这个是不可能的实现的。所以我们仔细分析可以知道其实能够对最短路产生影响的就是原图最短路上的边,所以我们只需要去枚举删除最短路径上面边然后求最短路即可,最后得到ans
3 这一题的n <= 1000 , m<=n*(n-1)/2 , 刚开始我用的SPFA,然后就开始TLE。后来知道了,有些时候SPFA的期望值中O(ke),有些题目会卡k,所以这个时候只能选择优先队列的Dij算法了。
4 题目用到了捆绑两种类型的pair<int , int>pii;

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<utility>
#include<queue>
using namespace std;
#define MAXN 2010
#define INF 0xFFFFFFF
typedef pair<int , int>pii;

int n , m;
int value[MAXN][MAXN];
int tmpFather[MAXN];
int father[MAXN];
int dis[MAXN];
int vis[MAXN];
priority_queue<pii , vector<pii> , greater<pii> >q;/*创建一个优先队列,并且声明为小整数*/

/*初始化*/
void init(){
   for(int i = 1 ; i <= n ; i++){
      for(int j = 1 ; j <= n ; j++)
         value[i][j] = INF;
      value[i][i] = 0;
   }
}

void Dij(int s){
   memset(vis , 0 , sizeof(vis));
   for(int i = 2 ; i <= n ; i++)
      dis[i] = INF;
   dis[s] = 0;
   q.push(make_pair(dis[s] , s));
   while(!q.empty()){
        pii u = q.top();
        q.pop();
        int x = u.second;/*x为点*/
        if(vis[x])
          continue;
        vis[x] = 1;
        for(int i = 1 ; i <= n ; i++){
           if(dis[i] > dis[x] + value[x][i]){
              dis[i] = dis[x] + value[x][i];
              father[i] = x;/*记录父亲*/
              q.push(make_pair(dis[i] , i));/*插入队列*/
           }
        }
   }
}

int main(){
  int a , b , v , tmp_v , ans;
  while(scanf("%d%d" , &n , &m) != EOF){
     init();
     for(int i = 0 ; i < m ; i++){
        scanf("%d%d%d" , &a , &b , &v);
        if(value[a][b] > v)
           value[a][b] = value[b][a] = v;
     }
     Dij(1);
     a = n;
     ans = 0;
     memcpy(tmpFather , father , sizeof(father));/*数组复制*/
     while(1){/*枚举要删除的边*/
        b = tmpFather[a];
        tmp_v = value[a][b];
        value[a][b] = value[b][a] = INF;
        Dij(1);
        if(ans < dis[n])
           ans = dis[n];
        value[a][b] = value[b][a] = tmp_v;
        a = tmpFather[a];
        if(a == 1)
           break;
     }
     printf("%d\n" , ans);
  }
  return 0;
}


目录
相关文章
|
算法 索引
LeetCode 214. Shortest Palindrome
给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。
56 0
LeetCode 214. Shortest Palindrome
|
索引
LeetCode 373. Find K Pairs with Smallest Sums
给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k。 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2。 找到和最小的 k 对数字 (u1,v1), (u2,v2) ... (uk,vk)。
114 0
LeetCode 373. Find K Pairs with Smallest Sums
LeetCode 409. Longest Palindrome
给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。 在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。
53 0
LeetCode 409. Longest Palindrome
|
SQL 关系型数据库 MySQL
LeetCode 613. Shortest Distance in a Line
LeetCode 613. Shortest Distance in a Line
77 0
|
人工智能
POJ 2533 Longest Ordered Subsequence
POJ 2533 Longest Ordered Subsequence
85 0
|
机器学习/深度学习
[LeetCode]--22. Generate Parentheses
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. For example, given n = 3, a solution set is: [ "((()))", "(()())", "(())()",
1081 0
[LeetCode]--409. Longest Palindrome
Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters. This is case sensitive, for example “Aa” i
1127 0
[LeetCode]--389. Find the Difference
Given two strings s and t which consist of only lowercase letters. String t is generated by random shuffling string s and then add one more letter at a random position. Find the letter th
1190 0