zoukankan      html  css  js  c++  java
  • POJ 2987 Firing (ISAP最小割)

    /* 这个题目建图是关键,具体还是靠自己体会了,需要注意的是结果要用__int64来保存。。*/

    #include <iostream>
    #include 
    <cstdio>
    #include 
    <memory.h>
    using namespace std;

    #define MAXN 6500
    #define MAXE 1000100
    #define INF 0x4fffffff

    int ne,nv,index,s,t,net[MAXN],cnt[MAXN];
    struct Edge{
        
    int next,pair;
        
    int v,cap,flow;
    }edge[MAXE];
    void dfs(const int& u) 
    {
        
    if( u == t) return ;
        cnt[u] 
    = 1;
        
    int i;
        
    for( i = net[u]; i != -1 ; i = edge[i].next)
            
    if(edge[i].cap>0 && !cnt[edge[i].v])
                dfs(edge[i].v);
    }
    void add(const int& u,const int& v,const int& val)
    {
        edge[index].next 
    = net[u];
        net[u] 
    = index;
        edge[index].v 
    = v;
        edge[index].cap 
    = val;
        edge[index].flow 
    = 0;
        edge[index].pair 
    = index + 1;
        
    ++index;

        edge[index].next 
    = net[v];
        net[v] 
    = index;
        edge[index].v 
    = u;
        edge[index].cap 
    = 0;
        edge[index].flow 
    = 0;
        edge[index].pair 
    = index - 1;
        
    ++index;
    }
    __int64 ISAP()
    {
        
    int numb[MAXN],dist[MAXN],curedge[MAXN],pre[MAXN];
        
    int cur_flow,u,tmp,neck,i;
        __int64 max_flow;
        memset(dist,
    0,sizeof(dist));
        memset(numb,
    0,sizeof(numb));
        memset(pre,
    -1,sizeof(pre));
        
    for(i = 1 ; i <= nv ; ++i)
            curedge[i] 
    = net[i];
        numb[nv] 
    = nv;
        max_flow 
    = 0;
        u 
    = s;
        
    while(dist[s] < nv)
        {
            
    /* first , check if has augmemt flow */
            
    if(u == t)
            {
                cur_flow 
    = INF;
                
    for(i = s; i != t;i = edge[curedge[i]].v) 
                {  
                    
    if(cur_flow > edge[curedge[i]].cap)
                    {
                        neck 
    = i;
                        cur_flow 
    = edge[curedge[i]].cap;
                    }
                }
                
    for(i = s; i != t; i = edge[curedge[i]].v)
                {
                    tmp 
    = curedge[i];
                    edge[tmp].cap 
    -= cur_flow;
                    edge[tmp].flow 
    += cur_flow;
                    tmp 
    = edge[tmp].pair;
                    edge[tmp].cap 
    += cur_flow;
                    edge[tmp].flow 
    -= cur_flow;
                }
                max_flow 
    += cur_flow;
                u 
    = neck;
            }
            
    /* if .... else ... */
            
    for(i = curedge[u]; i != -1; i = edge[i].next)
                
    if(edge[i].cap > 0 && dist[u] == dist[edge[i].v]+1)
                    
    break;
            
    if(i != -1)
            {
                curedge[u] 
    = i;
                pre[edge[i].v] 
    = u;
                u 
    = edge[i].v;
            }
    else{
                
    if(0 == --numb[dist[u]]) break;
                curedge[u] 
    = net[u];
                
    for(tmp = nv,i = net[u]; i != -1; i = edge[i].next)
                    
    if(edge[i].cap > 0)
                        tmp 
    = tmp<dist[edge[i].v]?tmp:dist[edge[i].v];
                dist[u] 
    = tmp + 1;
                
    ++numb[dist[u]];
                
    if(u != s) u = pre[u];
            }
        }
        
    return max_flow;
    }
    int main()
    {
        
    int i,j,a,b,val,n,m;
        __int64 sum 
    = 0;
        memset(net,
    -1,sizeof(net));
        scanf(
    "%d%d",&n,&m);
        s 
    = n + 1;
        t 
    = n + 2;
        nv 
    = t;
        
    for(i = 1;i <= n; ++i)
        {
            scanf(
    "%d",&val);
            
    if(val > 0){
                sum 
    +=val;
                add(s,i,val);
            }
            
    else
                add(i,t,
    -val);
        }
        
    for(i = 1; i <= m ;++i)
        {
            scanf(
    "%d%d",&a,&b);
            add(a,b,INF);
        }
        
    int ans = 0;
        memset(cnt,
    0,sizeof(cnt));
        __int64 tmp
    =ISAP();
        dfs(s);
        
    for(i = 1; i <= n; ++i) 
            
    if(cnt[i])
                
    ++ans;
        printf(
    "%d %I64d\n",ans,sum-tmp);
        
    return 0;
    }
        
  • 相关阅读:
    几个带双下划线的宏
    WM_COPYDATA消息机制 不同进程间发送结构体数据
    解锁ubuntu系统的root
    申请堆空间函数封装(两种方法)
    UITableView的分页的加载
    UIView设置成圆角
    iPhone开发:类似iChat的聊天泡泡
    iPhone中如何自定义tabbar
    android 底部选项卡(TabHost)
    Android 多个Activity选项卡实现
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1662742.html
Copyright © 2011-2022 走看看