zoukankan      html  css  js  c++  java
  • HDU 5889 最短路加网络流

    http://acm.hdu.edu.cn/showproblem.php?pid=5889


    题意: 一个无向图,每条边距离为1,从N走到1,的最短路。。然后每个路有个价值,求一下最小割


    思路:裸题。。手残BFS总是写错,后来换成SPFA枚举一下就好了。。注意!!!新图建单向边来跑最短路。


    代码:

    #include <iostream>
    #include <vector>
    #include <stdio.h>
    #include <queue>
    #include <cstring>
    #include <math.h>
    using namespace std;
    const int MAXN=1100;
    int maze[MAXN][MAXN];
    int Zdis[MAXN];
    int vis[MAXN];
    int gap[MAXN],dis[MAXN],pre[MAXN],cur[MAXN];
    
    const int INF=1e9+7;
    struct Edge{
        int v;
        int cost;
        Edge(int _v=0,int _cost=0):v(_v),cost(_cost) {}
    };
    struct T{
        int x,y,z;
        T(int _x=0,int _y=0,int _z=0):x(_x),y(_y),z(_z) {}
    };
    int tmp[MAXN];
    vector<Edge>E[MAXN];
    vector<T> Z;
    void addedge(int u,int v,int w){
        E[u].push_back(Edge(v,w));
    }
    void Add(int u,int v,int w){
        Z.push_back(T(u,v,w));
    }
    int cnt[MAXN];//每个点的入队列次数
    int dist[MAXN];
    int n,m;
    bool SPFA(int start,int n)
    {
        memset(vis,false,sizeof(vis));
        for(int i=1; i<=n; i++)dist[i]=INF;
        vis[start]=true;
        dist[start]=0;
        queue<int>que;
        while(!que.empty())que.pop();
        que.push(start);
        memset(cnt,0,sizeof(cnt));
        cnt[start]=1;
        while(!que.empty()){
            int u=que.front();
            que.pop();
            vis[u]=false;
            for(int i=0; i<E[u].size(); i++){
                int v=E[u][i].v;
                if(dist[v]>dist[u]+E[u][i].cost){
                    dist[v]=dist[u]+E[u][i].cost;
                    if(!vis[v]){
                        vis[v]=true;
                        que.push(v);
                        if(++cnt[v]>n)return false;      //cnt[i]为入队列次数,用来判定是否存在负环回路
                    }
                }
            }
        }
        return true;
    }
    
    void init(){
        for(int i=0;i<=n;i++) E[i].clear();
        Z.clear();
        memset(maze,0,sizeof(maze));
    }
    
    int sap(int start,int end,int nodenum){
        memset(cur,0,sizeof(cur));
        memset(dis,0,sizeof(dis));
        memset(gap,0,sizeof(gap));
        int u=pre[start]=start,maxflow=0,aug=-1;
        gap[0]=nodenum;
        while(dis[start]<nodenum){
            loop:
            for(int v=cur[u]; v<nodenum; v++)
                if(maze[u][v] && dis[u]==dis[v]+1){
                    if(aug==-1 || aug>maze[u][v])aug=maze[u][v];
                    pre[v]=u;
                    u=cur[u]=v;
                    if(v==end){
                        maxflow+=aug;
                        for(u=pre[u]; v!=start; v=u,u=pre[u]){
                            maze[u][v]-=aug;
                            maze[v][u]+=aug;
                        }
                        aug=-1;
                    }
                    goto loop;
                }
            int mindis=nodenum-1;
            for(int v=0; v<nodenum; v++)
                if(maze[u][v]&&mindis>dis[v]){
                    cur[u]=v;
                    mindis=dis[v];
                }
            if((--gap[dis[u]])==0)break;
            gap[dis[u]=mindis+1]++;
            u=pre[u];
        }
        return maxflow;
    }
    
    int main()
    {
        int t;
        cin>>t;
        while(t--){
            scanf("%d%d",&n,&m);
            int a,b,c;
            init();
            for(int i=0;i<m;i++){
                scanf("%d%d%d",&a,&b,&c);
                addedge(a,b,1);
                addedge(b,a,1);
                Add(a,b,c);
                Add(b,a,c);
            }
            if(!SPFA(1,n)){
                printf("0
    ");
                continue;
            }
            for(int i=0;i<=n;i++) tmp[i]=dist[i];
            SPFA(n,n);
            for (int i=0;i<Z.size();i++){
                if (dist[Z[i].x]+tmp[Z[i].y]+1==dist[1]) {
                    maze[Z[i].x-1][Z[i].y-1]+=Z[i].z;
                }
            }
            int ans=sap(n-1,0,n);
            printf("%d
    ",ans);
        }
        return 0;
    }


  • 相关阅读:
    Windows 8 应用的页面导航(1)
    开发 Windows 8 Bing地图应用(6)
    Windows 8 应用的页面导航(2)
    Windows 8 生命周期管理(4)
    删除DataTable重复列,只针对删除其中的一列重复的行
    Silverlight 数据库 Silverlight Database
    广告费用 会计处理及其改进
    Query to Join Delivery Details and MTL Material Table
    SAVEPOINT
    SYNCHRONIZE
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672542.html
Copyright © 2011-2022 走看看