zoukankan      html  css  js  c++  java
  • poj2987 最大权闭合图

    基础题。

    最小割后,与汇点相连的点都不要,然后从源点出发dfs一遍有多少相连的点即可。

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #define INF 99999999
    #define ll __int64
    using namespace std;
    const int maxn = 5100;
    struct node
    {
        int to;
        ll v;
        int flag;
        int next;
    }edge[(60000+maxn)*2];
    int index,pre[maxn],vis[maxn],S,T,cnt;
    void add(int x,int y,int z)
    {
        edge[index].to=y;
        edge[index].v=z;
        edge[index].flag=index+1;
        edge[index].next=pre[x];
        pre[x]=index++;
        edge[index].to=x;
        edge[index].v=0;
        edge[index].flag=index-1;
        edge[index].next=pre[y];
        pre[y]=index++;
    }
    ll dfs(int u,ll low)
    {
        int i;
        ll used=0;
        if(u==T)
            return low;
        for(i=pre[u];i!=-1&&used<low;i=edge[i].next)
        {
            if(edge[i].v&&vis[edge[i].to]==vis[u]+1)
            {
                ll a=dfs(edge[i].to,min(edge[i].v,low-used));
                edge[i].v-=a;
                edge[edge[i].flag].v+=a;
                used+=a;
            }
        }
        if(!used)
            vis[u]=-1;
        return used;
    }
    int BFS()
    {
        int i;
        memset(vis,-1,sizeof(vis));
        queue<int>q;
        vis[0]=1;
        q.push(0);
        while(!q.empty())
        {
            int t=q.front();
            q.pop();
            for(i=pre[t];i!=-1;i=edge[i].next)
            {
                if(edge[i].v&&vis[edge[i].to]<0)
                {
                    vis[edge[i].to]=vis[t]+1;
                    q.push(edge[i].to);
                }
            }
        }
        if(vis[T]>0)
            return 1;
        return 0;
    }
    void cnt_dfs(int u)
    {
        cnt++;
        vis[u]=1;
        for(int i=pre[u];i!=-1;i=edge[i].next)
        {
            if(!vis[edge[i].to]&&edge[i].v)
            {
                cnt_dfs(edge[i].to);
            }
        }
    }
    int main()
    {
        int n,m,i;
        while(~scanf("%d%d",&n,&m))
        {
            cnt=0;
            ll sum=0;
            index=1;
            memset(pre,-1,sizeof(pre));
            for(i=1;i<=n;i++)
            {
                ll x;
                scanf("%I64d",&x);
                if(x>0)
                {
                    sum+=x;
                    add(0,i,x);
                }
                else add(i,n+1,-x);
            }
            for(i=0;i<m;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                add(x,y,INF);
            }
            ll ans=0;
            S=0,T=n+1;
            while(BFS())
            {
          while(1){ ll a
    =dfs(0,INF); if(!a)break; ans+=a;
         } } memset(vis,
    0,sizeof(vis)); cnt_dfs(0); printf("%d %I64d ",cnt-1,sum-ans); } }
  • 相关阅读:
    创建型模式
    C# 数据结构 单链表反转
    没有人能随随便便成功
    If you are a new test manager – From google testing blog
    数据库惊魂
    foreach中的隐式类型转换
    C# 点滴 枚举
    C# 面试题目 单链表中删除重复数据
    0909关于编译原理课程的认识
    0920编译原理第二次上机作业
  • 原文地址:https://www.cnblogs.com/sweat123/p/4920450.html
Copyright © 2011-2022 走看看