USACO 4.2

草地排水洛谷传送门,草地排水USACO传送门

工序安排洛谷传送门,工序安排USACO传送门

完美的牛栏洛谷传送门,完美的牛栏USACO传送门


洛谷 2740 草地排水

代码(网络最大流)

/*
ID:lemondi1
LANG:C++
TASK:ditch
*/
#include <cstdio>
#include <cctype>
#include <queue>
#define rr register
using namespace std;
const int N=211,inf=1e7; long long ans;
struct node{int y,w,next;}e[N*50];
int dis[N],v[N],n,m,S,T,et,as[N];
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline bool bfs(int st){
	for (rr int i=1;i<=n;++i) dis[i]=0;
	rr queue<int>q; q.push(st),dis[st]=1;
	while (!q.empty()){
		rr int x=q.front(); q.pop();
		for (rr int i=as[x];i;i=e[i].next)
		if (e[i].w>0&&!dis[e[i].y]){
			dis[e[i].y]=dis[x]+1;
			if (e[i].y==T) return 1;
			q.push(e[i].y);
		}
	}
	return 0;
}
inline signed min(int a,int b){return a<b?a:b;}
inline signed dfs(int x,int now){
	if (x==T||!now) return now;
	rr int rest=0,f;
	for (rr int i=as[x];i;i=e[i].next)
	if (e[i].w>0&&dis[e[i].y]==dis[x]+1){
		f=dfs(e[i].y,min(now-rest,e[i].w)),
		rest+=f,e[i].w-=f,e[i^1].w+=f;
		if (now==rest) return now;
	}
	if (!rest) dis[x]=0;
	return rest;
}
signed main(){
	freopen("ditch.in","r",stdin);
	freopen("ditch.out","w",stdout);
	m=iut(),n=iut(),S=1,T=n,et=1;
	for (rr int i=1;i<=m;++i){
		rr int x=iut(),y=iut(),w=iut();
		e[++et]=(node){y,w,as[x]},as[x]=et;
		e[++et]=(node){x,0,as[y]},as[y]=et;
	}
	while (bfs(S)) ans+=dfs(S,inf);
	return !printf("%lld
",ans);
}

洛谷 2751 工序安排

分析

考虑开一个小根堆,第一问直接取出最小完成时间丢入下一次完成时间。

第二问考虑用第一道工序结束最晚的匹配第二道最早的这样时间一定不会更劣


代码

/*
ID:lemondi1
LANG:C++
TASK:job
*/
#include <cstdio>
#include <cctype>
#include <queue>
#define rr register
using namespace std;
struct rec{
	int x,w;
	inline bool operator <(const rec &t)const{
	    return x>t.x;
	}
};
priority_queue<rec>q;
int n,m0,m1,ans[1011],Ans,x;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans; 
}
signed main(){
	freopen("job.in","r",stdin);
	freopen("job.out","w",stdout);
	n=iut(),m0=iut(),m1=iut();
	for (rr int i=1;i<=m0;++i) x=iut(),q.push((rec){x,x});
	for (rr int i=1;i<=n;++i){
		rr rec t=q.top(); q.pop();
		ans[i]=t.x,t.x+=t.w,q.push(t);
	}
	while (!q.empty()) q.pop();
	for (rr int i=1;i<=m1;++i) x=iut(),q.push((rec){x,x});
	for (rr int i=n;i;--i){
		rr rec t=q.top(); q.pop();
		if (t.x+ans[i]>Ans) Ans=t.x+ans[i];
		t.x+=t.w,q.push(t); 
	}
	return !printf("%d %d
",ans[n],Ans); 
}

洛谷 1894 完美的牛栏

代码(二分图最大匹配)

/*
ID:lemondi1
LANG:C++
TASK:stall4 
*/
#include <cstdio>
#include <cctype>
#include <cstring> 
#define rr register
using namespace std;
const int N=211;
struct node{int y,next;}e[N*N];
int v[N],link[N],as[N],n,m,et,ans;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline bool match(int x){
	for (rr int i=as[x];i;i=e[i].next)
	if (!v[e[i].y]){
		v[e[i].y]=1;
		rr int q=link[e[i].y];
		link[e[i].y]=x;
		if (!q||match(q)) return 1;
		link[e[i].y]=q;
	}
	return 0;
}
signed main(){
	freopen("stall4.in","r",stdin);
	freopen("stall4.out","w",stdout);
	n=iut(),m=iut();
	for (rr int i=1;i<=n;++i)
	for (rr int j=iut();j;--j)
		e[++et]=(node){iut(),as[i]},as[i]=et;
	for (rr int i=1;i<=n;++i){
	    memset(v,0,sizeof(v));
	    if (match(i)) ++ans;
	}
	return !printf("%d
",ans);
}
原文地址:https://www.cnblogs.com/Spare-No-Effort/p/15397353.html