zoukankan      html  css  js  c++  java
  • hdu 3416 最大流+最短路

    题意

    有一个好兄弟和好兄弟的好妹妹在两个城市,现在给你n个城市,m个单向道路(重点,此信息在输入数据的提示里,我一开始没读仔细,wa卡爆了【while there may have no road from b to a】)

    问你有几种情况在每条路只通过一次的情况下有几种方式到达好妹妹的城市。2<=n<=1000, 0<=m<=100000

    思路

    先spfa正着搜start到各个点的最短路(存dp1[]),在spfa反着搜end到各个点的最短路(存dp2[])。

    因为是有向图,所以先存一个图a->b,用于start到各个点的最短路,然后另存一个图b->a,用于end到各个点的最短路

    用dp[i]+dp[j]+边长ij==最短路来确定是否这条边是最短路上的边。(毕竟最短路也有好几条)然后直接存进dinic里,流量是1。

    spfa的模板

    void spfa(int st,int x){
        mindis[st][x]=0;
        mem(vis,0);
        queue<int>q;
        q.push(st);
        while(!q.empty()){
            int u=q.front();q.pop();
            vis[u]=0;
            for(int i=head1[u];~i;i=edge1[i].next){
                int v=edge1[i].to,w=edge1[i].c;
                if(mindis[u][x]+w<mindis[v][x]){
                    mindis[v][x]=mindis[u][x]+w;
                    if(!vis[v]){
                        q.push(v);vis[v]=1;
                    }
                }
            }
    
        }
    }
    

    dinic(复杂度o(n*m*m))的模板

    int bfs(){
        queue<int>q;
        q.push(s);
        for(int i=1;i<N;i++){dis[i]=inf;}
        dis[s]=0;
        while(!q.empty()){
            int h=q.front(),i;q.pop();
            for(i=head[h];~i;i=edge[i].next){
                int v=edge[i].to;
                if(edge[i].c>edge[i].flow && dis[v]==inf){
                    dis[v]=dis[h]+1;q.push(v);
                }
            }
        }
        return dis[t]<inf;
    }
    int dfs(int x,int maxflow){
        if(x==t || maxflow==0){
            return maxflow;
        }
        int flow=0,i,f;
        for(i=cur[x];~i;i=edge[i].next){
            cur[x]=i;
            int v=edge[i].to;
            if(dis[v]==(dis[x]+1) && edge[i].c>edge[i].flow){
                f=dfs(v,min(maxflow,edge[i].c-edge[i].flow));
                edge[i].flow+=f;
                edge[i^1].flow-=f;
                flow+=f;
                maxflow-=f;
                if(maxflow==0){break;}
            }
        }
        return flow;
    }
    int dinic(){
        int flow=0;
        while(bfs()){
            memcpy(cur,head,sizeof(cur));
            flow+=dfs(s,inf);
        }
        return flow;
    }
    

    这题的ac代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define il inline
    #define it register int
    #define inf 99999999
    #define lowbit(x) (x)&(-x)
    #define pii pair<int,int>
    #define mak(a,b) make_pair(a,b)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define mod 1000000007
    const double pi=acos(-1.0);
    const int N=1e3+10,M=2e5+10;
    struct node{
        int to,next,c,flow;
    }edge[M],edge2[M],edge1[M];
    int cur[N],head[N],dis[N],tot,head2[N],tot2,head1[N],tot1;
    int n,m,s,t;
    int mindis[N][2];
    void inint(){
        tot=0;tot2=0;tot1=0;
        for(int i=0;i<N;i++){
            head[i]=head2[i]=head1[i]=-1;
            mindis[i][0]=mindis[i][1]=99999999;
        }
    }
    void add(int u,int v,int c){
        edge[tot].to=v;edge[tot].c=c;edge[tot].flow=0;
        edge[tot].next=head[u];head[u]=tot++;
        edge[tot].to=u;edge[tot].c=0;edge[tot].flow=0;
        edge[tot].next=head[v];head[v]=tot++;
    }
    void add2(int u,int v,int w){
        edge1[tot1].to=v;edge1[tot1].c=w;
        edge1[tot1].next=head1[u];head1[u]=tot1++;
        edge2[tot2].to=u;edge2[tot2].c=w;
        edge2[tot2].next=head2[v];head2[v]=tot2++;
    }
    int bfs(){
        queue<int>q;
        q.push(s);
        for(int i=1;i<N;i++){dis[i]=inf;}
        dis[s]=0;
        while(!q.empty()){
            int h=q.front(),i;q.pop();
            for(i=head[h];~i;i=edge[i].next){
                int v=edge[i].to;
                if(edge[i].c>edge[i].flow && dis[v]==inf){
                    dis[v]=dis[h]+1;q.push(v);
                }
            }
        }
        return dis[t]<inf;
    }
    int dfs(int x,int maxflow){
        if(x==t || maxflow==0){
            return maxflow;
        }
        int flow=0,i,f;
        for(i=cur[x];~i;i=edge[i].next){
            cur[x]=i;
            int v=edge[i].to;
            if(dis[v]==(dis[x]+1) && edge[i].c>edge[i].flow){
                f=dfs(v,min(maxflow,edge[i].c-edge[i].flow));
                edge[i].flow+=f;
                edge[i^1].flow-=f;
                flow+=f;
                maxflow-=f;
                if(maxflow==0){break;}
            }
        }
        return flow;
    }
    int dinic(){
        int flow=0;
        while(bfs()){
            memcpy(cur,head,sizeof(cur));
            flow+=dfs(s,inf);
        }
        return flow;
    }
    int vis[N];
    void spfa2(int st,int x){
        mindis[st][x]=0;
        mem(vis,0);
        queue<int>q;
        q.push(st);
        while(!q.empty()){
            int u=q.front();q.pop();vis[u]=0;
            for(int i=head2[u];~i;i=edge2[i].next){
                int v=edge2[i].to,w=edge2[i].c;
                if(mindis[u][x]+w<mindis[v][x]){
                    mindis[v][x]=mindis[u][x]+w;
                    if(!vis[v]){
                        q.push(v);vis[v]=1;
                    }
                }
            }
    
        }
    }
    void spfa(int st,int x){
        mindis[st][x]=0;
        mem(vis,0);
        queue<int>q;
        q.push(st);
        while(!q.empty()){
            int u=q.front();q.pop();vis[u]=0;
            for(int i=head1[u];~i;i=edge1[i].next){
                int v=edge1[i].to,w=edge1[i].c;
                if(mindis[u][x]+w<mindis[v][x]){
                    mindis[v][x]=mindis[u][x]+w;
                    if(!vis[v]){
                        q.push(v);vis[v]=1;
                    }
                }
            }
    
        }
    }
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            inint();
            scanf("%d%d",&n,&m);
            for(int i=0;i<m;i++){
                int v,w,u;
                scanf("%d%d%d",&u,&v,&w);
                add2(u,v,w);
            }
            scanf("%d%d",&s,&t);
            spfa(s,0);
            spfa2(t,1);
            //cout<<mindis[t][0]<<mindis[s][1]<<endl;
            for(int u=1;u<=n;u++){
                for(int i=head1[u];~i;i=edge1[i].next){
                     int v=edge1[i].to,w=edge1[i].c;
                     if(mindis[u][0]+mindis[v][1]+w==mindis[t][0]){
                        add(u,v,1);//cout<<u<<v<<endl;
                     }
                }
            }
            printf("%d
    ",dinic());
        }
    }
    

    这题容易wa和tle的注意事项

    tle一边就是你数组开小,wa可能是初始距离开小,或者是你题意读错,有向边看成无向图。。。

  • 相关阅读:
    DeepLearning4J 环境搭建【转】
    MxNet C++和python环境配置
    Vmvare + Ubuntu 16.04环境搭建 + 相关软件安装配置笔记【深度学习】
    caffe-windows环境配置(github上官方BVLC/caffe的推荐配置方法详解)
    pycaffe + anaconda2 + python2.7.配置
    【Win7 x64】+【annaconda3】+ 【python3.5.2】+【tensorflow-gpu】 [最终配置 gtx 940mx + Cuda8.0+cudnn v5.1 + tensorflow-gpu1.0.0 ]
    tensorboard的使用
    windows + python3.5.2 + anaconda3 + dlib 安装配置
    [python]selenium常用的操作
    [python]Pytest+selenium+git+jenkins持续集成
  • 原文地址:https://www.cnblogs.com/luoyugongxi/p/13746546.html
Copyright © 2011-2022 走看看