zoukankan      html  css  js  c++  java
  • P2685 [TJOI2012]桥

    Debug一下午,没想到把n写成m,出锅了。。。

    题意:1-n带权无向图,求删掉一条边使之后的最短路最长,输出这个值并输出删边的方案数

    正解:先跑两遍dij,然后把最短路的边标记,考虑最短路1---s------t-----n

       存在1----s-----x----y----t----n 删掉s---t(因为还要走最短路),所以要维护s---t的最小值(不经过s---t)

       因此可以用线段树,

       先bfs求出lr,(x:l=s,r=t )

       把1-----s------x------y------t------n的长度放在线段树上维护

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define int long long
    #define olinr return
    #define _ 0
    #define DB double
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            x=-x;
            putchar('-');
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    struct node
    {
        node *nxt;
        int to;
        int dis;
        bool vis;
        node()
        {
            nxt=NULL;
            to=dis=vis=0;
        }
    };
    struct tree
    {
        tree *ls;
        tree *rs;
        int l;
        int r;
        int dat;
        tree()
        {
            dat=l=r=0;
            ls=rs=NULL;
        }
    };
    typedef node* nod;
    typedef tree* tre;
    nod head[105050];
    int n;
    int m;
    int diss[105050];
    int dist[105050];
    bool vis[105050];
    int L[105050];
    int R[105050];
    int st[105050];
    int ans[105050];
    int cnt;
    priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
    queue<int>p;
    inline void add(int from,int to,int dis)
    {
        nod t=new node();
        t->to=to;
        t->dis=dis;
        t->nxt=head[from];
        head[from]=t;
    }
    inline void dij(int s,int *dis)
    {
        dis[s]=0;
        q.push(make_pair(dis[s],s));
        while(!q.empty())
        {
            int tp=q.top().second;
            q.pop();
            if(vis[tp]) continue;
            vis[tp]=true;
            for(nod i=head[tp];i;i=i->nxt)
            {
                if(dis[i->to]>dis[tp]+i->dis)
                {
                    dis[i->to]=dis[tp]+i->dis;
                    q.push(make_pair(dis[i->to],i->to));
                }
            }
        }
        memset(vis,0,sizeof vis);
    }
    inline void bfs(int s,int *dis,int *X)
    {
        p.push(st[s]);
        X[st[s]]=s;
        while(!p.empty())
        {
            int tp=p.front();
            p.pop();
            for(nod i=head[tp];i;i=i->nxt)
            {
                if(dis[i->to]==dis[tp]+i->dis&&!X[i->to]&&!vis[i->to])
                {
                    p.push(i->to);
                    X[i->to]=s;
                }
            }
        }
    }
    inline void build(tre now,int l,int r)
    {
        now->l=l;
        now->r=r;
        now->dat=0x7fffffff;
        if(l==r) return;
        int mid=(l+r)>>1;
        now->ls=new tree();
        now->rs=new tree();
        build(now->ls,l,mid);
        build(now->rs,mid+1,r);
    }
    inline void update(tre now,int x,int y,int k)
    {
        if(now->l>y||now->r<x) return;
        if(x<=now->l&&now->r<=y)
        {
            now->dat=min(now->dat,k);
            return;
        }
        update(now->ls,x,y,k);
        update(now->rs,x,y,k);
    }
    inline void query(tre now)
    {
        if(now->l==now->r)
        {
            ans[now->l]=now->dat;
            return;
        }
        now->ls->dat=min(now->ls->dat,now->dat);
        now->rs->dat=min(now->rs->dat,now->dat);
        query(now->ls);
        query(now->rs);
    }
    signed main()
    {
        n=read();
        m=read();
        for(int a,b,c,i=1;i<=m;i++)  //m写成n,死了一个多小时
        {
            a=read();
            b=read();
            c=read();
            add(a,b,c);
            add(b,a,c);
        }
        memset(diss,0x7f,sizeof diss);
        memset(dist,0x7f,sizeof dist);
        dij(1,diss);
        dij(n,dist);   //两遍dij
        for(int i=1;i!=n;)   //标记边
        {
            vis[i]=true;
            st[++cnt]=i;
            for(nod now=head[i];now;now=now->nxt)
            {
                if(dist[i]==dist[now->to]+now->dis)
                {
                    now->vis=true;
                    i=now->to;
                    break;
                }
            }
        }
        st[++cnt]=n;   //最短路的点
        vis[n]=true;
        for(int i=1;i<cnt;i++)
            bfs(i,diss,L);
        for(int i=cnt;i>=1;i--)    //两次bfs(图的联通)
            bfs(i,dist,R); 
        tre root=new tree();   //我TM就是写指针你咬我。。。。 
        build(root,1,cnt);    //建树
        for(int i=1;i<=n;i++)
            for(nod now=head[i];now!=NULL;now=now->nxt)   
            {
                if(now->vis) continue;
                if(L[i]<R[now->to]&&L[i]&&R[now->to])
                {
                    update(root,L[i],R[now->to]-1,diss[i]+dist[now->to]+now->dis);   //更新线段树
                }
            }
        query(root);//  求ans
        int num=0;
        int maxn=0;
        for(int i=1;i<cnt;i++)
        {
            if(ans[i]>maxn)  //累计
            {
                maxn=ans[i];
                num=1;
            }
            else if(ans[i]==maxn)
                num++;
        }
        if(maxn==diss[n]) num+=m-cnt+1;  //刚好是最短路;
        put(maxn);
        putchar(' ');
        put(num);
        return 0;
    }
  • 相关阅读:
    There is an overlap in the region chain修复
    There is an overlap in the region chain
    region xx not deployed on any region server
    python 中的re模块,正则表达式
    TCP粘包问题解析与解决
    yield from
    Git push提交时报错Permission denied(publickey)...Please make sure you have the correct access rights and the repository exists.
    mysql 中Varchar 与char的区别
    Mysql 字符集及排序规则
    请实现一个装饰器,限制该函数被调用的频率,如10秒一次
  • 原文地址:https://www.cnblogs.com/olinr/p/9629550.html
Copyright © 2011-2022 走看看