hdu 1595 find the longest of the shortest(dijstra + 枚举)

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

大致题意:

给一个图,让输出从中删除任意一条边后所得最短路径中最长的。。

思路:

直接枚举每条边想必是不行的。其实有些边是不需要枚举的,因为删除它们并不影响起点到终点的最短路。起作用的边都是未删边前的最短路径上的边,删除它们最短距离肯定增大,只需在这些最短距离中求最大的即可。

记录最短路径上的边,只需一个pre数组记录松弛时每个点的前驱节点。

#include <stdio.h>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#define LL long long
#define _LL __int64
using namespace std;

const int maxn = 1010;
const int INF = 0x3f3f3f3f;

int n,m;
int mapp[1010][1010];
int dis[maxn],vis[maxn];
int pre[maxn],pre1[maxn];
int ans;

void init()
{
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            if(i == j)
                mapp[i][j] = 0;
            else
                mapp[i][j] = INF;
        }
    }
    memset(pre,-1,sizeof(pre));
}

int dijstra(int s)
{
    memset(dis,INF,sizeof(dis));
    memset(vis,0,sizeof(vis));

    for(int i = 1; i <= n; i++)
    {
        dis[i] = mapp[s][i];
        pre[i] = s;
    }
    vis[s] = 1;
    pre[s] = -1;

    for(int i = 1; i < n; i++)
    {
        int min = INF,pos;
        for(int j = 1; j <= n; j++)
        {
            if(min > dis[j] && !vis[j])
            {
                min = dis[j];
                pos = j;
            }
        }

        vis[pos] = 1;
        for(int j = 1; j <= n; j++)
        {
            if(!vis[j] && dis[j] > dis[pos] + mapp[pos][j])
            {
                dis[j] = dis[pos] + mapp[pos][j];
                pre[j] = pos;
            }
        }
    }
    return dis[n];

}

void solve()
{
    memcpy(pre1,pre,sizeof(pre));
    ans = -1;

    int u = n;

    while(pre1[u] != -1)
    {
        int tmp = mapp[pre1[u]][u];

        mapp[pre1[u]][u] = mapp[u][pre1[u]] = INF; //删除该边

        int res = dijstra(1);
        if(res != INF)
            ans = max(ans,res);

        mapp[ pre1[u] ][u] = mapp[u][ pre1[u] ] = tmp;

        u = pre1[u];
    }
    printf("%d\n",ans);
}

int main()
{
    int u,v,w;
    while(~scanf("%d %d",&n,&m))
    {
        init();

        for(int i = 0; i < m; i++)
        {
            scanf("%d %d %d",&u,&v,&w);
            mapp[u][v] = mapp[v][u] = min(w,mapp[u][v]);
        }

        dijstra(1);
        solve();
    }
    return 0;
}
时间: 2024-09-30 19:57:42

hdu 1595 find the longest of the shortest(dijstra + 枚举)的相关文章

hdu 1595 最短路

题意是要我们求出最短路中一条路坏的情况下最大的时间: 我们先将最短路求出并记录路径,然后枚举最短路中每一条路坏的情况,求出最大的时间.. <span style="font-size:24px;">#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<cmath> using namespace st

hdu 1595 最短路算法dijkstra

find the longest of the shortest Time Limit: 1000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2094    Accepted Submission(s): 739 Problem Description Marica is very angry with Mirko because he found a new gi

HDU 5024 Wang Xifeng&#39;s Little Plot(暴力枚举+瞎搞)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5024 Problem Description <Dream of the Red Chamber>(also <The Story of the Stone>) is one of the Four Great Classical Novels of Chinese literature, and it is commonly regarded as the best one. Thi

HDU 1692 Destroy the Well of Life-卡时间-(枚举+剪枝)

题意:有n口井,编号为1到n,打破第i口井需要p[i]的能量,但是只要井被打破里面的水会流到下一口井,只要一口井的井水w[i]多余一个上限l[i]会自动打破,求打破第n口井需要的最少的能量 分析:hdu 把它归为dp,想了一会发现找不到最优子结构,然后看题解--根本不是dp,只是一个剪枝的题.或许有dp的解法,如果哪位大神知道还请指教.解题思路一旦局限在一个框框内很危险啊 代码: #include<iostream> using namespace std; int t,n,ans,w[100

HDU 4309 Seikimatsu Occult Tonneru(最大流+二进制枚举)

http://acm.hdu.edu.cn/showproblem.php?pid=4309 题意: 有n个城市,每个城市有num[i]个居民,有敌人要进行地毯式轰击,居民们要逃到隧道去.现在有隧道,隧道允许无限个人通过,并且可以容纳w个人:有桥,可以允许无限个人通过,但是不能容纳人:还有一些破桥,修复这些破桥需要w花费,如果不修复,那么最多只能通过一人,如果修复了,那么可以通过无限个人.求出在能安全到达隧道的最大人数时的最小代价.(上述都是单向边) 思路:出题人也是有心了..在题目中有说破桥的

HDU 4810 Wall Painting【二进制+异或+暴力枚举】

给出n个数 求从这n个数取k个数异或,所有情况得到的值(Cnk个值(可能有些相同))全加起来的值是多少 k从1到n 输出这n个数 这题一开始想毫无思绪 也没有说这n个数的大概范围,想用背包来着本来 结果发现它是这么解的 就样例来说,把四个数1,2,10,1拆开,当前是取k个数 0001 0010 1010 0001 对第四位来说,如果某些方案是取k个数异或后为0,那么等于 0*方案数,这个我们可以不用管它 如果某些方案是取2个数异或后为1,那么等于1*方案数 可以看到第四位有1个1,那么异或为1

HDU ACM 5224 Tom and paper 水题+暴力枚举

分析:因为长和宽都是整数,所以枚举判断是不是整数,再取最小的即可. #include<iostream> #include<cmath> using namespace std; int main() { int min; int a,i,T; ios::sync_with_stdio(false); cin>>T; while(T--) { cin>>a; min=1000000000; for(i=1;i<=sqrt(a);i++) if(a%i=

HDU 5137--How Many Maos Does the Guanxi Worth【枚举 &amp;&amp; 最短路 &amp;&amp; spfa】

How Many Maos Does the Guanxi Worth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 847    Accepted Submission(s): 322 Problem Description "Guanxi" is a very important word in Chinese. I

HDU 6186 CS Course【前后缀位运算枚举/线段树】

[前后缀枚举] #include<cstdio> #include<string> #include<cstdlib> #include<cmath> #include<iostream> #include<cstring> #include<set> #include<queue> #include<algorithm> #include<vector> #include<map