• HDU2485Destroying the bus stations 拆点网络流求割点个数


    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2485

    题目要求:删除最少的点,使得源点到汇点的距离大于k

    思路:拆点、建图求费用小于等于k的最大流

    #include <iostream>
    #include <cstring>
    #include <climits>
    #include <cstdio>
    #include <queue>
    using namespace std;
    #define min(x,y) (x)<(y)?(x):(y)
    const int maxm = 10005;
    const int maxn = 1100;
    
    struct node{
        int v,flow,cost,next;
    }edge[maxm];
    int head[maxn],dis[maxn],vis[maxn],pre[maxn],cur[maxn];
    int id,n,m,k;
    int sink,source;
    void add_edge(int u,int v,int flow,int cost){
        edge[id].v = v;edge[id].cost = cost;edge[id].flow = flow;edge[id].next = head[u];head[u] = id++;
        edge[id].v = u;edge[id].cost = -cost;edge[id].flow = 0  ;edge[id].next = head[v];head[v] = id++;
    }
    void init(){
        int u,v,i;
        source = 1,sink = n*2;
        memset(head,-1,sizeof(head));id = 0;
        for( i = 1; i <= m; i++){
            scanf("%d%d",&u,&v);
            add_edge(u+n,v,1,1);
        }
         for( i = 2; i < n; i++)//拆点
            add_edge(i,i+n,1,0);
        add_edge(1,n+1,5000000,0);
        add_edge(n,n+n,5000000,0);
    }
    
    int spfa(){
        memset(dis,-1,sizeof(dis));
        memset(vis,0,sizeof(vis));
        pre[source] = source;
        dis[source] = 0;
        vis[source] = 1;
        queue<int>que;
        que.push(source);
        while( !que.empty()){
            int u = que.front();
            que.pop();
            vis[u] = 0;
            for(int id = head[u]; id != -1; id = edge[id].next){
                int v = edge[id].v;
                if(edge[id].flow > 0 && (dis[v] == -1 || dis[v] > dis[u] + edge[id].cost )){
                    dis[v] = dis[u] + edge[id].cost;
                    pre[v] = u;cur[v] = id;
                    if(!vis[v] ){
                        vis[v] =  1;
                        que.push(v);
                    }
                }
            }
        }
        if(dis[sink] == -1 || dis[sink] > k)return 0;
        return 1;
    }
    
    int get_max(){
        int max_flow = 0;
        while(spfa())
        {
            //cout << dis[sink] << endl;
            max_flow += 1;
            int now = sink;
            while(now != source){
                edge[cur[now]].flow -= 1;
                edge[cur[now]^1].flow += 1;
                now = pre[now];
            }
        }
        return max_flow;
    }
    int main(){
        freopen("in.txt","r",stdin);
        while(~scanf("%d%d%d",&n,&m,&k),n||m||k){
            init();
            printf("%d
    ",get_max());
        }
        return 0;
    }
    

      

  • 相关阅读:
    #define中的特殊符号
    c++ windows下计时
    c++内存池
    u3d 场景资源打包
    Unity3d 动态加载材质方法
    Unity3D Shader基础教程
    Unity3D Shader入门指南(一)
    Unreal发展史
    阴影锥(shadow volume)原理与展望
    软硬RAID 和 不常见的RAID
  • 原文地址:https://www.cnblogs.com/LUO257316/p/3228103.html
Copyright © 2020-2023  润新知