1.处理内容
网络流部
费用流模板 1题
神建图 2题
判欧拉回路 1题
上下界网络流 1题
动态规划部
斜率优化 2题
2.网络流部
(1)运输问题
网络流24题之一http://www.cogs.pro/cogs/problem/problem.php?pid=739
直接甩版
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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]]
(2)卡牌配对
方法见黄学长博客http://hzwer.com/7428.html
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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]]
(4)bridges(POI2014)
欧拉回路之判定方式:
随机决定出入度,如果建图能跑平衡就合法
bzoj只求最大风力,那路径我们求不求?
我决定偷懒
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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
#include
#include
#include
#include
#include
#include
#include
#include
#include
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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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(lslope(que[r],i)) --r;
que[++r]=i;
}
write(f[n]);
return 0;
}
(2)特别行动队(APIO2010)
居然是我们国家出的,并不是很难
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1911
方法基本同上
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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(lslope(que[r],i)) --r;
que[++r]=i;
}
write(f[n]);
return 0;
}
哇,已经开学十二天了。