zoukankan      html  css  js  c++  java
  • 勤奋的杨老师(二)

    勤奋的杨老师(二)

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 32768K,其他语言65536K
    64bit IO Format: %lld

    题目描述

    众所周知,杨老师是一位十分勤奋的老师,他非常的热爱学习。

    勤奋的他为自己罗列了一个学习清单,共有n个知识点,他可以有选择的进行学习。

    每个知识点都会对应0个或1个或多个先修知识点(只有学会了先修知识点才能学习该知识点),同时每个知识点都有一个智慧值和一个智力消耗值。

    杨老师希望在进行过激烈的学习之后,他的收获可以·量化为所有学过的题的智慧值的和与智力消耗值的和的差值。请问,这个值最大是多少?

    输入描述:

    第一行:一个整数n(n<=500)接下来n行,每行两个整数,代表第i个知识点的智慧值和智力消耗值接下来若干行,每行2个整数u, v,代表u是v的先修知识点。

    输出描述:

    一行,表示杨老师的收获的最大值
    示例1

    输入

    4
    5 1
    2 1
    1 2
    1 2
    3 1
    2 4
    2 1

    输出

    4

    最大权闭合子图。最大权闭合子图的权值等于所有正权点之和减去最小割。
    mark一下建图方法。
    参考博客:
    https://www.cnblogs.com/TreeDream/p/5942354.html,其中着重要注意他是如何证明最大权的。
    #include<bits/stdc++.h>
    #define N 505
    #define inf LLONG_MAX/2
    using namespace std;
    
    typedef struct
    {
        int v;
        long long flow;    
    }ss;
    
    ss edg[N*N];
    int now_edges=0;
    vector<int>edges[N];
    
    void addedge(int u,int v,long long flow)
    {
        edges[u].push_back(now_edges);
        edg[now_edges++]=(ss){v,flow};
        edges[v].push_back(now_edges);
        edg[now_edges++]=(ss){u,0};
    }
    
    int dis[N],S,T;
    
    bool bfs()
    {
        queue<int>q;
        memset(dis,0,sizeof(dis));
        q.push(S);
        dis[S]=1;
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
            
            int Size=edges[now].size();
            for(int i=0;i<Size;i++)
            {
                ss e=edg[edges[now][i]];
                
                if(e.flow>0&&dis[e.v]==0)
                {
                    dis[e.v]=dis[now]+1;
                    q.push(e.v);
                }    
            }
        }    
    
        if(dis[T]==0)return 0;
        return 1;
    
    }
    
    int current[N];
    long long dfs(int now,long long maxflow)
    {
        if(now==T)return maxflow;
        int Size=edges[now].size();
        for(int i=current[now];i<Size;i++)
        {
            current[now]=i;
            ss &e=edg[edges[now][i]];
            
            if(e.flow>0&&dis[e.v]==dis[now]+1)
            {
                long long Flow=dfs(e.v,min(maxflow,e.flow));
                if(Flow!=0)
                {
                    e.flow-=Flow;
                    edg[edges[now][i]^1].flow+=Flow;
                    return Flow;
                
                }
            }
        }
        return 0;
    }
    
    long long dinic()
    {
        long long ans=0,flow;
        while(bfs())
        {
            memset(current,0,sizeof(current));
            while(flow=dfs(S,inf))ans+=flow;
        
        }
        return ans;
    }
    
    int main()
    {
        int n,a,b;
        scanf("%d",&n);
        S=n+1;
        T=n+2;
        long long tot=0;
        
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d",&a,&b);
            if(a>=b)addedge(S,i,a-b),tot+=a-b;
            else
            addedge(i,T,b-a);
        } 
        
        while(scanf("%d %d",&a,&b)==2)addedge(b,a,inf);
    
        printf("%lld
    ",tot-dinic());
        return 0;
    
    }
    View Code
  • 相关阅读:
    Jenkins系列——使用SonarQube进行代码质量检查
    HTTP1.0工作原理
    Jenkins系列——使用checkstyle进行代码规范检查
    Jenkins系列——定时构建
    Hadoop环境搭建
    eclipse3.4+对的处理插件(附SVN插件安装实例)
    MD5
    RedHat6.5更新软件源
    ubuntu软件推荐
    disconf系列【2】——解决zk部署情况为空的问题
  • 原文地址:https://www.cnblogs.com/tian-luo/p/9515408.html
Copyright © 2011-2022 走看看