• 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可能是初始距离开小,或者是你题意读错,有向边看成无向图。。。

  • 相关阅读:
    导航条按钮的设置UIBarButtonItem
    动态修改app build版本CFBundleVersion
    iOS应用图片尺寸制作脚本
    iPad所有平板型号屏幕尺寸
    一个小时学会Git
    NSLog的各种打印格式符和打印CGRect相关结构体
    Linux上统计文件夹下文件个数以及目录个数
    Privacy Description
    iOS开发微信支付的介绍与实现
    iOS开发苹果内购的介绍与实现
  • 原文地址:https://www.cnblogs.com/luoyugongxi/p/13746546.html
Copyright © 2020-2023  润新知