• hdu 6582(最短路+最小割)


    传送门

    题意:

    给你一张有向图,现在你需要删除一些边,每次删除的花费是边的权值,使得最短路增大,现在问你最小的花费。

    题解:

    如果要使得最短路增大,显然是删掉最短路上的一些边。我们发现,原图的最短路也能够形成一张( ext{DAG}),如果我们要使得最短路增大,等价于要求一个最小的花费,使得我们可以破坏这个( ext{DAG}),而显然这个东西就是最小割。因此我们只需要把原图的最短路建边,之后在新的图上跑最小割即可。至于在原图最短路上建边,我们只需要对以(1)号结点以及(n)号结点分别求最短路,之后对于每一条边所连接的两个结点(u)(v),如果(dis_{1u}+dis_{nv}+val_{uv}=dis_{1n})则证明该条边是最短路上的边。

    看了下数据,看起来好像不太强大啊,为了不T,在这样的数据量下最好还是得用优秀的最大流算法……

    代码:

    #include <bits/stdc++.h>
    #define maxn 30005
    using namespace std;
    typedef long long ll;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    int head1[maxn],cnt1;
    int head2[maxn],cnt2;
    
    int n,m;
    struct edge{
        int to,next,from;
        long long cost;
    }q1[maxn],q2[maxn];
    void add_edge(int from,int to,int cost,int *head,int &cnt,edge *q){
        q[cnt].to=to;
        q[cnt].from=from;
        q[cnt].cost=cost;
        q[cnt].next=head[from];
        head[from]=cnt++;
    }
    typedef pair<int,ll>P;
    ll d1[maxn],d2[maxn],e[maxn],h[maxn],cnth[maxn];
    void diji(int s,int *head,edge *q,ll *d){
        for(int i=1;i<=n;i++) d[i]=INF;
        priority_queue<P,vector<P>,greater<P> >que;
        d[s]=0;
        que.push(P(0,s));
        while(!que.empty()){
            P p=que.top();
            que.pop();
            int x=p.second;
            if(d[x]<p.first) continue;
            for(int i=head[x];i!=-1;i=q[i].next){
                edge id=q[i];
                if(d[id.to]>d[x]+id.cost){
                    d[id.to]=d[x]+id.cost;
                    que.push((P(d[id.to],id.to)));
                }
            }
        }
    }
    //hlpp求解最大流
    int head3[maxn],cntt=2;
    struct Node{
        int to,next;
        ll val;
    }qq[maxn<<1];
    int vis[maxn];
    int sp,ep;
    struct cmp{
        inline bool operator()(int a,int b) const{
            return h[a]<h[b];
        }
    };
    void addedge(int from,int to,int val){
        qq[cntt].to=to;
        qq[cntt].val=val;
        qq[cntt].next=head3[from];
        head3[from]=cntt++;
    }
    void add_edge2(int from,int to,int val){
        addedge(from,to,val);
        addedge(to,from,0);
    }
    void bfs(){
        memset(h,0x3f,sizeof(h));
        h[ep]=0;
        queue<int>que;
        que.push(ep);
        while(!que.empty()){
            int x=que.front();
            que.pop();
            vis[x]=0;
            for(int i=head3[x];i!=-1;i=qq[i].next){
                int to=qq[i].to;
                if(qq[i^1].val&&h[to]>h[x]+1){
                    h[to]=h[x]+1;
                    if(vis[to]==0){
                        que.push(to);
                        vis[to]=1;
                    }
                }
            }
        }
        return;
    }
    void init(int *head,int &cnt){
        for(int i=0;i<maxn;i++) head[i]=-1;
        memset(vis,0,sizeof(vis));
        memset(cnth,0,sizeof(cnth));
        memset(e,0,sizeof(e));
        cnt=0;
    }
    priority_queue<int,vector<int>,cmp>Q;
    inline void push_(int x){
        for(int i=head3[x];i!=-1;i=qq[i].next){
            int to=qq[i].to;
            if(qq[i].val&&h[to]+1==h[x]){
                int mi=min(qq[i].val,e[x]);
                qq[i].val-=mi;
                qq[i^1].val+=mi;
                e[x]-=mi;
                e[to]+=mi;
                if(vis[to]==0&&to!=ep&&to!=sp){
                    Q.push(to);
                    vis[to]=1;
                }
                if(e[x]==0)break;
            }
        }
    }
    inline void relabel(int x){
        h[x]=INF;
        for(int i=head3[x];i!=-1;i=qq[i].next){
            int to=qq[i].to;
            if(qq[i].val&&h[to]+1<h[x]){
                h[x]=h[to]+1;
            }
        }
    }
    ll hlpp(){
        register int i;
        bfs();
        if(h[sp]==INF)return 0;
        h[sp]=n;
        for(i=1;i<=n;i++)if(h[i]<INF)cnth[h[i]]++;
        for(i=head3[sp];i!=-1;i=qq[i].next){
            int to=qq[i].to;
            ll mi=qq[i].val;
            if(mi){
                e[sp]-=mi;
                e[to]+=mi;
                qq[i].val-=mi;
                qq[i^1].val+=mi;
                if(to!=ep&&vis[to]==0&&to!=sp){
                    Q.push(to);
                    vis[to]=1;
                }
            }
        }
        while(!Q.empty()){
            int x=Q.top();
            vis[x]=0;
            Q.pop();
            push_(x);
            if(e[x]){
                cnth[h[x]]--;
                if(cnth[h[x]]==0){
                    for(int i=1;i<=n;i++){
                        if(i!=sp&&i!=ep&&h[i]>h[x]&&h[i]<n+1){
                            h[i]=n+1;
                        }
                    }
                }
                relabel(x);
                cnth[h[x]]++;
                Q.push(x);
                vis[x]=1;
            }
        }
        return e[ep];
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&m);
            init(head1,cnt1);
            init(head2,cnt2);
            init(head3,cntt);
            cntt=2;
            for(int i=1;i<=m;i++){
                int from,to,cost;
                scanf("%d%d%d",&from,&to,&cost);
                add_edge(from,to,cost,head1,cnt1,q1);
                add_edge(to,from,cost,head2,cnt2,q2);
            }
            diji(1,head1,q1,d1);
            diji(n,head2,q2,d2);
            if(d1[n]==INF){
                puts("0");
                continue;
            }
            sp=1,ep=n;
            for(int i=1;i<=n;i++){
                for(int j=head1[i];j!=-1;j=q1[j].next){
                    int to=q1[j].to;
                    int from=q1[j].from;
                    int val=q1[j].cost;
                    if(d1[from]+d2[to]==d1[n]-val){
                        add_edge2(from,to,val);
                    }
                }
            }
            printf("%lld
    ",hlpp());
        }
        return 0;
    }
    
    
  • 相关阅读:
    十大开源Web应用安全测试工具
    HC大会,华为联合合作伙伴发布一站式物联网IoT开发工具小熊派BearPi
    漫谈边缘计算(四):赢家是软还是硬
    漫谈边缘计算(三):5G的好拍档
    漫谈边缘计算(二):各怀心事的玩家
    漫谈边缘计算(一):边缘计算是大势所趋
    从小小后视镜看物联网的生态(下)
    机器学习笔记(四)---- 逻辑回归的多分类
    机器学习笔记(三)---- 逻辑回归(二分类)
    机器学习笔记(二)---- 线性回归
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11228767.html
Copyright © 2020-2023  润新知