zoukankan      html  css  js  c++  java
  • [HDU1595] find the longest of the shortest

    题目链接:###

    点我

    题意:###

    给定一个(n)个点,(m)条边的带权无向图,起点为(1),终点为(n),现在可以删去其中的一条边,求一种删边方案使得剩下图的最短路值最大,输出这个最短路的长度。
    题目保证删去任意一条边都能使得(1)(n)连通,且边权均为正值。

    题目分析:###

    首先用(Dijkstra)跑出原图的最短路,由于在最短路之外删边对图的最短路没有影响,所以考虑在最短路上删边,直接暴力跑(Dijkstra)
    需要注意的是,这里不会超时的原因是一个有(n)个点的正权无向图的最短路总共包含的边数不会超过(n-1)。最坏的情况是把每个点都经过一遍,这样就会有(n-1)条边在最短路上,而如果最短路的边数(>n-1),就说明有节点被经过了两遍,(既然要从这里第二次经过,为什么还要到外面绕一圈而不是直接走呢?)这和最短路矛盾,而在实际情况中,最短路的边数甚至远远达不到这个上界。所以在最短路上删边暴力跑(Dij)的最坏时间复杂度是(O(n*log(n)+n^2*log(n)))

    代码:###

    #include<bits/stdc++.h>
    #define N (1000+5)
    #define M (1000000+5)
    using namespace std;
    priority_queue< pair<int,int> > q;
    inline int read(){
        int cnt=0,f=1;char c;
        c=getchar();
        while(!isdigit(c)){
            if(c=='-') f=-f;
            c=getchar();
        }
        while(isdigit(c)){
            cnt=cnt*10+c-'0';
            c=getchar();
        }
        return cnt*f;
    }
    int n,m,first[N],nxt[M],to[M],w[M],d[N],tot,a,b,v,ans=-1;
    bool vis[N];
    int path[N];
    void add(int x,int y,int z) { 
        nxt[++tot]=first[x];
        first[x]=tot;
        to[tot]=y;
        w[tot]=z;
    }
    
    void dijkstra(){
        memset(d,0x3f,sizeof(d));
        memset(vis,0,sizeof(vis));
        d[1]=0;
        q.push(make_pair(0,1));
        while(q.size()) {
            int u=q.top().second; q.pop();
            if(vis[u])continue;
            vis[u]=1;
            for(register int i=first[u];i;i=nxt[i]) {
                int v=to[i];int z=w[i];
                if(d[v]>d[u]+z) {
                    d[v]=d[u]+z;
                    path[v]=u;
                    q.push(make_pair(-d[v],v));
                }
            }
        }
    }
    
    void dijkstra2(int x,int y) {
        memset(d,0x3f,sizeof(d));
        memset(vis,0,sizeof(vis));
        d[1]=0;
        q.push(make_pair(0,1));
        while(q.size()) {
            int u=q.top().second; q.pop();
            if(vis[u])continue;
            vis[u]=1;
            for(register int i=first[u];i;i=nxt[i]) {
                int v=to[i];int z=w[i];
                if((u==x&&v==y)||(u==y&&v==x))continue;
                if(d[v]>d[u]+z) {
                    d[v]=d[u]+z;
                    q.push(make_pair(-d[v],v));
                }
            }
        }
    }
    
    int main(){
        while(scanf("%d%d",&n,&m)!=EOF) {
            tot=0;
            for(register int i=1;i<=n;i++) path[i]=-1;
            for(register int i=1;i<=n;i++) first[i]=0;
            ans=-1;
            for(register int i=1;i<=m;i++) {
                a=read();b=read();v=read();
                add(a,b,v);add(b,a,v);
            }
            dijkstra();
            for(register int i=n;i!=-1;i=path[i]) {
    //            cout<<i<<" "<<path[i]<<endl;
                dijkstra2(i,path[i]);
                ans=max(ans,d[n]);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    搜索1009
    搜索1004
    Java文件操作
    搜索1007
    连接查询
    SQL学习——数据类型
    SQL学习——基本语法
    <转载>GIS数据下载网站大全
    DOM查询练习
    day09【继承、super、this、抽象类】
  • 原文地址:https://www.cnblogs.com/kma093/p/10387907.html
Copyright © 2011-2022 走看看