9.12第一轮扫荡战果

20 篇文章 0 订阅
7 篇文章 0 订阅

1.处理内容

网络流部

费用流模板 1题

神建图 2题

判欧拉回路 1题

上下界网络流 1题

动态规划部

斜率优化 2题

2.网络流部

(1)运输问题

网络流24题之一http://www.cogs.pro/cogs/problem/problem.php?pid=739

直接甩版

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#define int long long
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 222
#define sten 222222
int tot,first[stan],nxt[sten],to[stan],ret,n,m,a[stan][stan],v[stan],S,T,goal[sten],wide[sten],cost[sten];
bool exi[stan],real[stan];
void addedge(int a,int b,int c,int d){
	++tot;nxt[tot]=first[a];first[a]=tot;goal[tot]=b;wide[tot]=c;cost[tot]=d;
	++tot;nxt[tot]=first[b];first[b]=tot;goal[tot]=a;wide[tot]=0;cost[tot]=-d;
	return ;
}
bool spfa(){
	static int que[sten];
	int q=1;
	for(int i=S;i<=T;++i)
		to[i]=999999999,exi[i]=false;
	to[S]=0;que[q]=S;
	for(int i=1;i<=q;++i){
		int u=que[i];real[u]=false;
		for(int p=first[u];p;p=nxt[p])
			if(wide[p]&&to[goal[p]]>to[u]+cost[p]){
				to[goal[p]]=to[u]+cost[p];
				if(!real[goal[p]]){
					real[goal[p]]=true;
					que[++q]=goal[p]; 
				}
			}
	}
	return to[T]!=999999999;
}
bool lpfa(){
	static int que[sten];
	int q=1;
	for(int i=S;i<=T;++i)
		to[i]=-999999999,exi[i]=false;
	to[S]=0;que[q]=S;
	for(int i=1;i<=q;++i){
		int u=que[i];real[u]=false;
		for(int p=first[u];p;p=nxt[p])
			if(wide[p]&&to[goal[p]]<to[u]+cost[p]){
				to[goal[p]]=to[u]+cost[p];
				if(!real[goal[p]]){
					real[goal[p]]=true;
					que[++q]=goal[p]; 
				}
			}
	}
	return to[T]!=-999999999;
}
int dfs(int u,int flow){
	if(u==T){
		ret+=to[T]*flow;
		return flow;
	}
	int ret=0,data;
	exi[u]=true;
	for(int p=first[u];p;p=nxt[p])
		if(wide[p]&&to[goal[p]]==to[u]+cost[p]&&!exi[goal[p]]){
			data=dfs(goal[p],min(flow-ret,wide[p]));
			if(data){
				wide[p]-=data;
				wide[p^1]+=data;
				ret+=data;
				if(ret==flow) return flow;
			}
		}
	return ret;
}
int dinic(int x){
	if(!x){
		ret=0;
		while(spfa()) dfs(S,999999999);
		return ret;
	}else{
		ret=0;
		while(lpfa()) dfs(S,999999999);
		return ret;
	}
}
signed main(){
	freopen("tran.in","r",stdin);
	freopen("tran.out","w",stdout);
	tot=1;
	m=read();n=read();
	S=0;T=m+n+1;
	for(int i=1;i<=m;++i){
		v[i]=read();
		addedge(S,i,v[i],0);
	}
	for(int i=1;i<=n;++i){
		v[i+m]=read();
		addedge(i+m,T,v[i+m],0);
	}
	for(int i=1;i<=m;++i)
		for(int j=1;j<=n;++j){
			a[i][j]=read();
			addedge(i,j+m,999999999,a[i][j]);
		}
	write(dinic(0));puts(" ");
	tot=1;
	memset(first,0,sizeof(first));
	for(int i=1;i<=n+m;++i){
		if(i<=m) addedge(S,i,v[i],0);
		else addedge(i,T,v[i],0);
	}
	for(int i=1;i<=m;++i)
		for(int j=1;j<=n;++j){
			addedge(i,j+m,999999999,a[i][j]);
		}
	write(dinic(1));
	return 0;
}
(2)卡牌配对

方法见黄学长博客http://hzwer.com/7428.html

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline long long read(){
	long long i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 33333
#define sten 4444444
#define stin 77777 
#define ston 55
#define stun 222
struct card{
	int x,y,z;
}a[stan],b[stan];
int tot,nxt[sten],first[stin],goal[sten],wide[sten];
int level[stin],pri[ston],cnti,v[stun][ston];
bool exi[stun];
int n1,n2,ind,id[ston][ston],S,T;
void addedge(int a,int b,int c){
	++tot,nxt[tot]=first[a];first[a]=tot;goal[tot]=b;wide[tot]=c;
	++tot,nxt[tot]=first[b];first[b]=tot;goal[tot]=a;wide[tot]=0;
	return ;
}
bool bfs(){
	static int que[stin];
	int q=1;
	for(int i=S;i<=T;++i)
		level[i]=-1;
	level[S]=0;
	que[q]=S;
	for(int i=1;i<=q;++i){
		int u=que[i];
		for(int p=first[u];p;p=nxt[p])
			if(wide[p]&&level[goal[p]]==-1){
				level[goal[p]]=level[u]+1;
				que[++q]=goal[p];
				if(goal[p]==T) return true;
			}
	}
	return false;
}
int dfs(int u,int flow){
	if(u==T) return flow;
	int ret=0,data;
	for(int p=first[u];p;p=nxt[p])
		if(wide[p]&&level[goal[p]]==level[u]+1){
			data=dfs(goal[p],min(flow-ret,wide[p]));
			wide[p]-=data;
			wide[p^1]+=data;
			ret+=data;
			if(ret==flow) return ret;
		}
	level[u]=-1;
	return ret;
}
int dinic(){
	int ret=0;
	while(bfs())
		ret+=dfs(S,999999999);
	return ret;
}
void preact(){
	for(int i=2;i<=200;++i){
		if(!exi[i])	pri[++cnti]=i;
		for(int j=1;j<=cnti&&pri[j]*i<=200;++j){
			exi[i*pri[j]]=true;
			if(i%pri[j]==0) break;
		}
	}
	for(int i=2;i<=200;++i)
		for(int j=1;j<=cnti;++j)
			if(i%pri[j]==0) v[i][++v[i][0]]=j;
	for(int i=1;i<=cnti;++i)
		for(int j=1;j<=cnti;++j)
			id[i][j]=++ind;
	return ;
}
void build(int t,int f)
{
	int x,y,z;
	if(!f)x=a[t].x,y=a[t].y,z=a[t].z;
	else x=b[t].x,y=b[t].y,z=b[t].z;
	for(int i=1;i<=v[x][0];++i)
		for(int j=1;j<=v[y][0];++j)
			if(!f)addedge(t,n1+n2+id[v[x][i]][v[y][j]],1);
			else addedge(n1+n2+id[v[x][i]][v[y][j]],n1+t,1);
	for(int i=1;i<=v[x][0];++i)
		for(int j=1;j<=v[z][0];++j)
			if(!f)addedge(t,n1+n2+id[v[x][i]][v[z][j]]+46*46,1);
			else addedge(n1+n2+id[v[x][i]][v[z][j]]+46*46,n1+t,1);
	for(int i=1;i<=v[y][0];++i)
		for(int j=1;j<=v[z][0];++j)
			if(!f)addedge(t,n1+n2+id[v[y][i]][v[z][j]]+46*46*2,1);
			else addedge(n1+n2+id[v[y][i]][v[z][j]]+46*46*2,n1+t,1);
}
signed main(){
	tot=1;
	n1=read();n2=read();
	S=0,T=n1+n2+46*46*3+1;
	for(int i=1;i<=n1;++i){
		a[i].x=read();
		a[i].y=read();
		a[i].z=read();
	}
	for(int i=1;i<=n2;++i){
		b[i].x=read();
		b[i].y=read();
		b[i].z=read();
	}
	preact();
	for(int i=1;i<=n1;++i){
		addedge(S,i,1);
		build(i,0);
	}
	for(int i=1;i<=n2;++i){
		addedge(n1+i,T,1);
		build(i,1);
	}
	write(dinic());
	return 0;
}
(3)学姐的逛街计划

题目自带题解我也是服气的https://www.vijos.org/p/1891

直接把图一刀砍成三层边再加上k的限制同层无费用流动就解决了,666

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#define int long long
using namespace std;
inline long long read(){
	long long i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 111111
#define sten 2222222
int tot,nxt[sten],first[stan],goal[sten],wide[sten],cost[sten];
int to[stan],ret,n,k,c[stan],S,T;
bool exi[stan],real[stan];
void addedge(int a,int b,int c,int d){
	++tot;nxt[tot]=first[a];first[a]=tot;goal[tot]=b;wide[tot]=c;cost[tot]=d;
	++tot;nxt[tot]=first[b];first[b]=tot;goal[tot]=a;wide[tot]=0;cost[tot]=-d;
	return ;
}
bool lpfa(){
	static int que[stan];
	int q=1;
	for(int i=S;i<=T;++i)
		to[i]=-999999999,exi[i]=false;
	to[S]=0;que[q]=S;
	for(int i=1;i<=q;++i){
		int u=que[i];real[u]=false;
		for(int p=first[u];p;p=nxt[p])
			if(wide[p]&&to[goal[p]]<to[u]+cost[p]){
				to[goal[p]]=to[u]+cost[p];
				if(!real[goal[p]]){
					real[goal[p]]=true;
					que[++q]=goal[p];
				}
			}
	}
	return to[T]!=-999999999;
}
int dfs(int pos,int flow){
	if(pos==T){
		ret+=to[T]*flow;
		return flow;
	}
	int ret=0,data;
	exi[pos]=true;
	for(int p=first[pos];p;p=nxt[p])
		if(wide[p]&&to[goal[p]]==to[pos]+cost[p]&&!exi[goal[p]]){
			data=dfs(goal[p],min(flow-ret,wide[p]));
			if(data){
				wide[p]-=data;
				wide[p^1]+=data;
				ret+=data;
				if(ret==flow) return flow;
			}
		}
	return ret;
}
int solve(){
	ret=0;
	while(lpfa()) dfs(S,999999999);
	return ret;
}
signed main(){
	tot=1;
	n=read();k=read();
	for(int i=1;i<=3*n;++i)
		c[i]=read();
	S=0,T=2*n+3;
	for(int i=2;i<=n+1;++i)
		addedge(S,i,1,c[i-1]);
	for(int i=n+2;i<=n*2+1;++i)
		addedge(i-n,i,1,c[i-1]);
	for(int i=n+2;i<=n*2+1;++i)
		addedge(i,2*n+2,1,c[i-1+n]);
	for(int i=2;i<=2*n+2;++i)
		addedge(i-1,i,k,0);
	addedge(S,1,k,0);
	addedge(2*n+2,T,k,0);
	write(solve());
	return 0;
}
(4)bridges(POI2014)

欧拉回路之判定方式:

随机决定出入度,如果建图能跑平衡就合法

bzoj只求最大风力,那路径我们求不求?

我决定偷懒

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 1111
#define sten 2222
int tot,nxt[sten],first[stan],goal[stan],wide[sten];
int level[stan],S,T;
int degree[stan],cnt;
int n,m,u[stan],v[stan],c[stan],d[stan],l,r,ans;
void addedge(int a,int b,int c){
	++tot,nxt[tot]=first[a];first[a]=tot;goal[tot]=b;wide[tot]=c;
	++tot,nxt[tot]=first[b];first[b]=tot;goal[tot]=a;wide[tot]=0;
	return ;
}
bool bfs(){
	static int que[stan];
	int q=1;
	for(int i=1;i<=T;++i)
		level[i]=-1;
	level[S]=0;
	que[q]=S;
	for(int i=1;i<=q;++i){
		int u=que[i];
		for(int p=first[u];p;p=nxt[p])
			if(wide[p]&&level[goal[p]]==-1){
				level[goal[p]]=level[u]+1;
				que[++q]=goal[p];
				if(goal[p]==T) return true;
			}
	}
	return false;
}
int dfs(int u,int flow){
	if(u==T) return flow;
	int ret=0,data;
	for(int p=first[u];p;p=nxt[p])
		if(wide[p]&&level[goal[p]]==level[u]+1){
			data=dfs(goal[p],min(flow-ret,wide[p]));
			wide[p]-=data;
			wide[p^1]+=data;
			ret+=data;
			if(ret==flow) return ret;
		}
	level[u]=-1;
	return ret;
}
int dinic(){
	int ret=0;
	while(bfs())
		ret+=dfs(S,999999999);
	return ret;
}
void build(int ave){
	memset(first,0,sizeof(first));
	memset(degree,0,sizeof(degree));
	tot=1,cnt=0;
	for(int i=1;i<=m;++i){
		if(c[i]<=ave){
			--degree[u[i]];
			++degree[v[i]];
		}
		if(d[i]<=ave)
			addedge(u[i],v[i],1);
	}
	for(int i=1;i<=n;++i){
		if(degree[i]>0){
			cnt+=(degree[i]/2);
			addedge(i,T,degree[i]/2);
		}else if(degree[i]<0)
			addedge(S,i,-degree[i]/2);
	}
}
bool check(int mid){
	for(int i=1;i<=n;++i)
		if(degree[i]&1) return false;
	return dinic()==cnt;
}
signed main(){
	n=read();m=read();
	S=0;T=n+1;
	l=1111,r=-1;
	for(int i=1;i<=m;++i){
		u[i]=read();v[i]=read();c[i]=read();d[i]=read();
		if(c[i]>d[i]){
			swap(c[i],d[i]);
			swap(u[i],v[i]);
		}
		l=min(c[i],l);
		r=max(d[i],r);
	}
	ans=-1;
	while(l<=r){
		int mid=l+r>>1;
		build(mid);
		if(check(mid)){
			ans=mid;
			r=mid-1;
		}else
			l=mid+1;
	}
	if(ans==-1)puts("NIE");
	else write(ans);
	return 0;
}
(5)支线剧情(AHOI2014)

跪烂PoPoQQQ大爷http://blog.csdn.net/popoqqq/article/details/43024221

蒟蒻表示只想用dinic瞎搞搞

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline long long read(){
	long long i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 333
#define sten 111111
int tot=1,nxt[sten],first[stan],goal[sten],wide[sten],cost[sten];
int to[stan],ret,n,S,T,m,b,t;
bool exi[stan],real[stan];
void addedge(int a,int b,int c,int d){
	++tot;nxt[tot]=first[a];first[a]=tot;goal[tot]=b;wide[tot]=c;cost[tot]=d;
	++tot;nxt[tot]=first[b];first[b]=tot;goal[tot]=a;wide[tot]=0;cost[tot]=-d;
	return ;
}
bool spfa(){
	static int que[stan];
	int q=1;
	for(int i=S;i<=T;++i)
		to[i]=999999999,exi[i]=false;
	to[S]=0;que[q]=S;
	for(int i=1;i<=q;++i){
		int u=que[i];real[u]=false;
		for(int p=first[u];p;p=nxt[p])
			if(wide[p]&&to[goal[p]]>to[u]+cost[p]){
				to[goal[p]]=to[u]+cost[p];
				if(!real[goal[p]]){
					real[goal[p]]=true;
					que[++q]=goal[p];
				}
			}
	}
	return to[T]!=999999999;
}
int dfs(int pos,int flow){
	if(pos==T){
		ret+=to[T]*flow;
		return flow;
	}
	int ret=0,data;
	exi[pos]=true;
	for(int p=first[pos];p;p=nxt[p])
		if(wide[p]&&to[goal[p]]==to[pos]+cost[p]&&!exi[goal[p]]){
			data=dfs(goal[p],min(flow-ret,wide[p]));
			if(data){
				wide[p]-=data;
				wide[p^1]+=data;
				ret+=data;
				if(ret==flow) return flow;
			}
		}
	return ret;
}
int dinic(){
	ret=0;
	while(spfa()) dfs(S,999999999);
	return ret;
}
signed main(){
	n=read(); S=0;T=n+1;
	for(int i=1;i<=n;++i){
		m=read();
		for(int j=1;j<=m;++j){
			b=read();t=read();
			addedge(S,b,1,t);
			addedge(i,b,999999999,t);
		}
		addedge(i,T,m,0);
		if(i!=1) addedge(i,1,999999999,0);
	}
	write(dinic());
	return 0;
}
3.动态规划部

(1)仓库建设(ZJOI2007)

啊,十年之前

题面:http://www.lydsy.com/JudgeOnline/problem.php?id=1096

前缀和预处理一下即可

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#define int long long
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 1111111
int n,x[stan],p[stan],c[stan],sum[stan],pre[stan],que[stan],l,r,f[stan];
double slope(int k,int j){
	return double(f[k]-f[j]+pre[k]-pre[j])/double(sum[k]-sum[j]);
}
signed main(){
	n=read();
	for(int i=1;i<=n;++i){
		x[i]=read();p[i]=read();c[i]=read();
		sum[i]=p[i]+sum[i-1];
		pre[i]=pre[i-1]+p[i]*x[i];
	}
	for(int i=1;i<=n;++i){
		while(l<r&&slope(que[l],que[l+1])<x[i]) ++l;
		int k=que[l];
		f[i]=f[k]+(sum[i]-sum[k])*x[i]-pre[i]+pre[k]+c[i];
		while(l<r&&slope(que[r-1],que[r])>slope(que[r],i)) --r;
		que[++r]=i;
	}
	write(f[n]);
	return 0;
}
(2)特别行动队(APIO2010)

居然是我们国家出的,并不是很难

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1911

方法基本同上

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#define int long long
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 1111111
int n,a,b,c,x,sum[stan],f[stan],l,r,que[stan];
double slope(int k,int j){
	return double(f[k]-f[j]+a*(sum[k]-sum[j])*(sum[k]+sum[j])-b*(sum[k]-sum[j]))/double(2*a*(sum[k]-sum[j]));
}
signed main(){
	n=read();
	a=read();b=read();c=read();
	for(int i=1;i<=n;++i){
		x=read();
		sum[i]=sum[i-1]+x;
	}
	for(int i=1;i<=n;++i){
		while(l<r&&slope(que[l],que[l+1])<sum[i]) ++l;
		int k=que[l];
		f[i]=f[k]+a*(sum[i]-sum[k])*(sum[i]-sum[k])+b*(sum[i]-sum[k])+c;
		while(l<r&&slope(que[r-1],que[r])>slope(que[r],i)) --r;
		que[++r]=i;
	}
	write(f[n]);
	return 0;
}
哇,已经开学十二天了。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值