洛谷 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\n",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\n",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\n",ans);
}