• pku 2112 二分答案 最大流


    #include <iostream>
    using namespace std;
    #define MAXN 250
    #define INF 2110000000
    #define MIN(x,y) (x<y?x:y)
    int map[MAXN][MAXN];
    int K,C,M,n;
    int s,t;
    int dis[MAXN][MAXN];
    int mat[MAXN][MAXN];
    void floyd()
    {
    int i,j,k;
    for(k=1;k<=n;k++)
    {
    for(i=1;i<=n;i++)
    {
    for(j=1;j<=n;j++)
    {
    if(dis[i][j]>dis[i][k]+dis[k][j])
    dis[i][j]
    =dis[i][k]+dis[k][j];
    }
    }
    }
    }
    void inti(int mindis)
    {
    int i,j;
    memset(mat,
    0,sizeof(mat));
    for(i=K+1;i<=n;i++)
    mat[s][i]
    =1;
    for(i=1;i<=K;i++)
    mat[i][t]
    =M;
    for(i=K+1;i<=n;i++)
    {
    for(j=1;j<=K;j++)
    {
    if(mindis>=dis[i][j])
    mat[i][j]
    =1;
    }
    }
    }
    int max_flow(int num,int map[][MAXN],int source,int sink)//参数含义:结点数量 网络 源点 汇点
    {
    int my_queue[MAXN],queue_first,queue_end;//数组做队列 实现BFS搜索路径
    int pre[MAXN],min_flow[MAXN];//记录结点的父节点 当前路径中最小的一段的值,也即限制值
    int flow[MAXN][MAXN];//记录当前网络中的流
    int ans=0;//最终结果
    memset(flow,0,sizeof(flow));
    while(1)//一直循环,直到不存在增广路径
    {
    queue_first
    =0;//初始化队列
    queue_end=0;
    my_queue[queue_end
    ++]=source;
    memset(pre,
    -1,sizeof(pre));
    min_flow[source]
    =INF;
    pre[source]
    =-2;//源点的父节点需特殊标示
    while(queue_first<queue_end)//BFS寻找增广路径
    {
    int temp=my_queue[queue_first++];//出队列
    for(int i=0;i<num;i++)//由结点temp往外扩展
    {
    if(pre[i]==-1&&flow[temp][i]<map[temp][i])//当结点i还未被探索到,并且还有可用流量
    {
    my_queue[queue_end
    ++]=i;//加入队列
    pre[i]=temp;//标示父节点
    min_flow[i]=MIN(min_flow[temp],(map[temp][i]-flow[temp][i]));//求得min_flow
    }
    }
    if(pre[sink]!=-1)//sink的父节点不为初始值,说明BFS已经找到了一条路径
    {
    int k=sink;
    while(pre[k]>=0)
    {
    flow[pre[k]][k]
    +=min_flow[sink];//将新的流量加入flow
    flow[k][pre[k]]=-flow[pre[k]][k];
    k
    =pre[k];
    }
    break;
    }
    }
    if(pre[sink]==-1) return ans;//不存在增广路径,返回
    else ans+=min_flow[sink];
    }
    return ans;
    }
    int main()
    {
    int i,j;
    while(scanf("%d%d%d",&K,&C,&M)!=EOF)
    {
    n
    =K+C;
    for(i=1;i<=n;i++)
    {
    for(j=1;j<=n;j++)
    {
    scanf(
    "%d",&dis[i][j]);
    if(dis[i][j]==0) dis[i][j]=999999999;
    }
    }
    floyd();
    s
    =0;
    t
    =n+1;
    int left=0,right=10000,mid;
    while(left<right)
    {
    mid
    =(left+right)/2;
    inti(mid);
    int temp=max_flow(n+2,mat,s,t);
    if(temp>=C) right=mid;
    else left=mid+1;
    }
    printf(
    "%d\n",right);
    }
    return 0;
    }
  • 相关阅读:
    CS231n 学习笔记(1) Image CLassification
    caffe-winsows封装成dll
    Nuget安装程序包源
    PCA降维demo
    AI方面的国际会议
    caffe solver
    caffe数据层
    一些有意思的技术博客
    js cookie 设置
    knockout.validation.js 异步校验
  • 原文地址:https://www.cnblogs.com/ACAC/p/1739648.html
Copyright © 2020-2023  润新知