• POJ 2112:floyd+网络流+二分


    一开始以为是费用流。。半天搞不出

    经过学弟讲解才知道是这么个问题

    先用floyd求出任意两个事物间的最短距离,题目要求在所有牛都能找到机器的前提下,最长距离最小(其实看到这样的字眼就应该想到二分),我们可以二分答案

    对于每一个答案建图跑网络流,只建容量小于mid的边,看看是否所有的牛都能找到机器就好

    不知道为何用sap模板老是TLE - -||明明感觉比dinic要快啊..

    #include"cstdio"
    #include"queue"
    #include"cmath"
    #include"stack"
    #include"iostream"
    #include"algorithm"
    #include"cstring"
    #include"queue"
    #include"map"
    #include"set"
    #include"vector"
    #define ll long long
    #define mems(a,b) memset(a,b,sizeof(a))
    
    using namespace std;
    const int MAXN = 350;
    const int MAXE = 20050;
    const int INF = 0x3f3f3f3f;
    struct node{
        int s,e,next,val;
        node(){}
        node(int a,int b,int c,int d):s(a),e(b),next(c),val(d){}
    }edge[MAXE];
    int tot,src,des,m,k,c;
    int first[MAXN],dep[MAXN],gap[MAXN];
    int mat[MAXN][MAXN];
    
    void init(){
        tot=0;
        mems(first,-1);
    }
    
    void addedge(int u,int v,int w){
        //cout<<u<<'	'<<v<<'	'<<w<<endl;
        edge[tot]=node(u,v,first[u],w);
        first[u]=tot++;
        edge[tot]=node(v,u,first[v],0);
        first[v]=tot++;
    }
    
    
    
    bool bfs(int src,int des){
        mems(dep,-1);
        queue<int> q;
        while(!q.empty()) q.pop();
        q.push(src);
        dep[src]=0;
        while(!q.empty()){
            int cur=q.front();q.pop();
            for(int i=first[cur];i!=-1;i=edge[i].next){
                int v=edge[i].e;
                if(dep[v]!=-1||edge[i].val<=0) continue;
                dep[v]=dep[cur]+1;
                q.push(v);
            }
        }
        return dep[des]!=-1;
    }
    
    int dfs(int s,int t,int flow){
        if(s==t) return flow;
        int newflow=0;
        for(int i=first[s];i!=-1;i=edge[i].next){
            int v=edge[i].e;
            int w=edge[i].val;
            if(dep[v]!=dep[s]+1||!edge[i].val)
                continue;
            int temp=dfs(v,t,min(w,flow-newflow));
            newflow+=temp;
            edge[i].val-=temp;
            edge[i^1].val+=temp;
            if(newflow==flow) break;
        }
        return newflow;
    }
    
    bool dinic(int s,int t,int c){
        int sum=0;
        while(bfs(s,t)){
            sum+=dfs(s,t,INF);
        }
        return sum==c;
    }
    
    void build(int maxv){
        init();
        for(int i=1;i<=k;i++) addedge(src,i,m);
        for(int i=k+1;i<=k+c;i++) addedge(i,des,1);
    
        for(int i=1;i<=k;i++)
        for(int j=k+1;j<=k+c;j++) if(mat[i][j]<=maxv) addedge(i,j,1);
    }
    
    void floyd(int N){
        for(int k=1;k<=N;k++)
        for(int i=1;i<=N;i++)
        for(int j=1;j<=N;j++) mat[i][j]=min(mat[i][j],mat[i][k]+mat[k][j]);
    }
    
    int main(){
        //freopen("in.txt","r",stdin);
        while(~scanf("%d%d%d",&k,&c,&m)){
            for(int i=1;i<=k+c;i++)
            for(int j=1;j<=k+c;j++){
                scanf("%d",&mat[i][j]);
                if(!mat[i][j]) mat[i][j]=INF;
            }
            floyd(k+c);
            src=0;
            des=k+c+1;
    
            int low=0,high=INF,mid;
            int ans=INF;
            while(low<=high){
                int mid=(low+high)>>1;
                build(mid);
                if(dinic(src,des,c)){
                    ans=min(ans,mid);
                    high=mid-1;
                }
                else low=mid+1;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    io学习三
    io学习二
    io学习一
    多线程学习(十五)
    spring源码阅读(四)
    多线程学习(十四)
    多线程学习(十三)
    设计模式(一)
    spring源码阅读(三)
    spring源码阅读(二)
  • 原文地址:https://www.cnblogs.com/luxiaoming/p/5146499.html
Copyright © 2020-2023  润新知