题目:https://www.luogu.org/problemnew/show/P4009
网络流24题中不是网络流的最短路题;
把每个点拆成各个油量上的点,根据要求连边即可;
注意:点数最大为100*100*11,因为虽然k<=10,但还有k=0的状态!(竟然因为边界调了一晚上)
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; typedef long long ll; queue<int>q; int const MAXN=110005,inf=1e9;//MAXN不可为100005 int n,k,a,b,c,nd[15][105][105],cnt,ct=1,head[MAXN]; int dis[MAXN]; bool vis[MAXN]; struct N{ int to,next,w; N(int t=0,int n=0,int w=0):to(t),next(n),w(w) {} }edge[MAXN*50]; void spfa() { memset(dis,63,sizeof dis); int s=nd[k][1][1]; dis[s]=0;vis[s]=1;q.push(s); while(q.size()) { int x=q.front();q.pop();vis[x]=0; // cout<<x<<endl; for(int i=head[x];i;i=edge[i].next) { int u=edge[i].to; if(dis[u]>dis[x]+edge[i].w) { // cout<<dis[x]<<endl; dis[u]=dis[x]+edge[i].w; if(!vis[u])vis[u]=1,q.push(u); } } // cout<<q.size()<<endl; } // cout<<"spfa"<<endl; // ll mn=inf; // for(int l=0;l<=k;l++) // mn=min(mn,dis[nd[l][n][n]]); printf("%d",dis[cnt+1]); } int main() { scanf("%d%d%d%d%d",&n,&k,&a,&b,&c);//a加油 b返回 c建库 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int l=0;l<=k;l++) nd[l][i][j]=++cnt; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { bool d; scanf("%d",&d); if(!d) { edge[++ct]=N(nd[k][i][j],head[nd[0][i][j]],a+c),head[nd[0][i][j]]=ct; for(int l=1;l<=k;l++) { int x=nd[l][i][j]; if(i>1)edge[++ct]=N(nd[l-1][i-1][j],head[x],b),head[x]=ct; if(j>1)edge[++ct]=N(nd[l-1][i][j-1],head[x],b),head[x]=ct; if(i<n)edge[++ct]=N(nd[l-1][i+1][j],head[x],0),head[x]=ct; if(j<n)edge[++ct]=N(nd[l-1][i][j+1],head[x],0),head[x]=ct; // if(l<k)edge[++ct]=N(nd[k][i][j],head[x],a+c),head[x]=ct;//不优! } } if(d) { int x=nd[k][i][j]; for(int l=0;l<k;l++) edge[++ct]=N(x,head[nd[l][i][j]],a),head[nd[l][i][j]]=ct; if(i>1)edge[++ct]=N(nd[k-1][i-1][j],head[x],b),head[x]=ct; if(j>1)edge[++ct]=N(nd[k-1][i][j-1],head[x],b),head[x]=ct; if(i<n)edge[++ct]=N(nd[k-1][i+1][j],head[x],0),head[x]=ct; if(j<n)edge[++ct]=N(nd[k-1][i][j+1],head[x],0),head[x]=ct; } } for(int l=0;l<=k;l++) edge[++ct]=N(cnt+1,head[nd[l][n][n]],0),head[nd[l][n][n]]=ct; // cout<<cnt<<endl; spfa(); return 0; }