列表

详情


NC15828. 勤奋的杨老师(二)

描述

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

勤奋的他为自己罗列了一个学习清单,共有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

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 7ms, 内存消耗: 944K, 提交时间: 2020-07-22 13:27:52

#include<bits/stdc++.h>
#define min(a,b) a<b?a:b
#define nx 100005
using namespace std;
int h[505],to[nx],c[nx],nxt[nx],cnt=1;
int cur[505],dis[505],val[505],n,m,s,t;
inline void add(int u,int v,int l){
	to[++cnt]=v,c[cnt]=l,nxt[cnt]=h[u],h[u]=cnt;
}
inline bool bfs(){
	memcpy(cur,h,sizeof h),memset(dis,0,sizeof dis);
	int q[505],f=1,r=0,now,v;
	q[++r]=s,dis[s]=1;
	while(f<=r){
		now=q[f++];
		for(int i=h[now];i;i=nxt[i])
			if(c[i]&&!dis[v=to[i]]){
				dis[v]=dis[now]+1,q[++r]=v;
				if(v==t)return 1;
			}
	}return 0;
}
inline int dfs(int x,int now){
	if(x==t||!now)return now;
	int re=0,f,v;
	for(int i=cur[x];i;i=nxt[i]){
		cur[x]=i;
		if(c[i]&&dis[v=to[i]]==dis[x]+1){
			f=dfs(v,min(now-re,c[i]));
			c[i]-=f,c[i^1]+=f,re+=f;
			if(now-re==0)break;
		}
	}return re;
}
int main(){
	scanf("%d",&n),s=n+1,t=n+2;
	int u,v;
	for(int i=1;i<=n;++i)
		scanf("%d%d",&u,&v),val[i]=u-v;
	while(~scanf("%d%d",&u,&v))
		add(v,u,505),add(u,v,0);
	int ans=0;
	for(int i=1;i<=n;++i){
		if(val[i]>0)ans+=val[i],add(s,i,val[i]),add(i,s,0);
		if(val[i]<0)add(i,t,-val[i]),add(t,i,0);
	}
	while(bfs())ans-=dfs(s,0x3f3f3f3f);
	printf("%d",ans);
}

C++11(clang++ 3.9) 解法, 执行用时: 273ms, 内存消耗: 2012K, 提交时间: 2018-05-04 16:09:13

#include <bits/stdc++.h>
using namespace std;
#define maxn 505
int n,u,v,f[maxn],in[maxn],ans;
bool line[maxn][maxn];
vector<int>Q[maxn];
set<vector<bool> >W;
vector<bool>path;
void DFS(int num)
{
    if(W.count(path)) return ;
    ans=max(ans,num);
    W.insert(path);
    for(int i=1;i<=n;i++)
    {
        if(path[i]){
            for(int j=0;j<Q[i].size();j++){
                if(-- in[Q[i][j]] == 0) path[Q[i][j]]=1;
            } path[i]=0;
            DFS(num+f[i]);
            for(int j=0;j<Q[i].size();j++){
                if(!in[Q[i][j]]) path[Q[i][j]]=0;
                in[Q[i][j]]++;
            } path[i]=1;
        }
    }
}
int main()
{
    cin>>n;ans=0;
    for(int i=1;i<=n;i++) {cin>>u>>v;f[i]=u-v;}
    while(cin>>u>>v){
        in[v]++;
        Q[u].push_back(v);
    }
    path = vector<bool>(n+1,0);
    for(int i=1;i<=n;i++) if(!in[i]) path[i]=1;
    DFS(0); cout<<ans<<endl;
    return 0;
}

上一题